web-dev-qa-db-fra.com

choix aléatoire numpy dans Tensorflow

Existe-t-il une fonction équivalente au choix aléatoire numpy dans Tensorflow? Numpy permet d’obtenir un élément au hasard dans la liste avec ses poids. 

 np.random.choice([1,2,3,5], 1, p=[0.1, 0, 0.3, 0.6, 0])

Ce code sélectionnera un élément de la liste donnée avec p poids. 

19
seleucia

Non, mais vous pouvez obtenir le même résultat en utilisant tf.multinomial :

elems = tf.convert_to_tensor([1,2,3,5])
samples = tf.multinomial(tf.log([[1, 0, 0.3, 0.6]]), 1) # note log-prob
elems[tf.cast(samples[0][0], tf.int32)].eval()
Out: 1
elems[tf.cast(samples[0][0], tf.int32)].eval()
Out: 5

La partie [0][0] est ici, car multinomial attend une ligne de probabilités de journal non normalisées pour chaque élément du lot et a également une autre dimension pour le nombre d'échantillons.

16
sygi

Si, au lieu d'échantillonner des éléments aléatoires d'un tenseur à une dimension, vous souhaitez échantillonner de manière aléatoire des lignes d'un tenseur à n dimensions, vous pouvez combiner tf.multinomial et tf.gather.

def _random_choice(inputs, n_samples):
    """
    With replacement.
    Params:
      inputs (Tensor): Shape [n_states, n_features]
      n_samples (int): The number of random samples to take.
    Returns:
      sampled_inputs (Tensor): Shape [n_samples, n_features]
    """
    # (1, n_states) since multinomial requires 2D logits.
    uniform_log_prob = tf.expand_dims(tf.zeros(tf.shape(inputs)[0]), 0)

    ind = tf.multinomial(uniform_log_prob, n_samples)
    ind = tf.squeeze(ind, 0, name="random_choice_ind")  # (n_samples,)

    return tf.gather(inputs, ind, name="random_choice")
2
protagonist

Mon équipe et moi avons eu le même problème avec l'obligation de conserver toutes les opérations en tant qu'opérateurs de tensorflow et de mettre en œuvre une version «sans remplacement».

Solution:

def tf_random_choice_no_replacement_v1(one_dim_input, num_indices_to_drop=3):

    input_length = tf.shape(one_dim_input)[0]

    # create uniform distribution over the sequence
    # for tf.__version__<1.11 use tf.random_uniform - no underscore in function name
    uniform_distribution = tf.random.uniform(
        shape=[input_length],
        minval=0,
        maxval=None,
        dtype=tf.float32,
        seed=None,
        name=None
    )

    # grab the indices of the greatest num_words_to_drop values from the distibution
    _, indices_to_keep = tf.nn.top_k(uniform_distribution, input_length - num_indices_to_drop)
    sorted_indices_to_keep = tf.contrib.framework.sort(indices_to_keep)

    # gather indices from the input array using the filtered actual array
    result = tf.gather(one_dim_input, sorted_indices_to_keep)
    return result

L'idée derrière ce code est de produire une distribution uniforme aléatoire avec une dimensionnalité égale à la dimension du vecteur sur laquelle vous souhaitez effectuer la sélection de choix. Étant donné que la distribution produira une séquence de nombres unique et pouvant être classée, vous pouvez utiliser les indices des k premières positions et les utiliser comme choix. Puisque la position des k premiers sera aussi aléatoire que la distribution uniforme, cela revient à effectuer un choix aléatoire sans remplacement.

Cela peut effectuer l'opération de choix sur n'importe quelle séquence 1-d du tensorflow.

0
PaulG