wake-up-neo.com

numpy zufällige Wahl in Tensorflow

Gibt es eine gleichwertige Funktion, um die zufällige Auswahl in Tensorflow zu wählen. In numpy können wir einen Artikel mit seinen Gewichtungen zufällig aus der angegebenen Liste erhalten. 

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

Dieser Code wählt ein Element aus der angegebenen Liste mit p-Gewichten aus. 

19
seleucia

Nein, aber Sie können dasselbe Ergebnis mit tf.multinomial erzielen:

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

Der [0][0]-Teil ist hier, da multinomial eine Reihe nicht normalisierter Log-Wahrscheinlichkeiten für jedes Element des Stapels erwartet und außerdem eine andere Dimension für die Anzahl der Proben hat.

16
sygi

Wenn Sie, anstatt zufällige Elemente aus einem 1-dimensionalen Tensor abzutasten, Zeilen aus einem n-dimensionalen Tensor zufällig abtasten möchten, können Sie tf.multinomial und tf.gather kombinieren.

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

Mein Team und ich hatten das gleiche Problem mit der Anforderung, alle Operationen als Tensorflow-Ops beizubehalten und eine Version ohne Ersatz zu implementieren.

Lösung:

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

Die Idee hinter diesem Code besteht darin, eine zufällige gleichmäßige Verteilung mit einer Dimensionalität zu erzeugen, die der Größe des Vektors entspricht, über den die Auswahlauswahl erfolgen soll. Da die Verteilung eine Folge von Zahlen erzeugt, die eindeutig sind und in eine Rangfolge gebracht werden können, können Sie die Indizes der oberen k-Positionen verwenden und diese als Auswahlmöglichkeiten verwenden. Da die Position des obersten k so zufällig ist wie die gleichmäßige Verteilung, entspricht dies einer zufälligen Auswahl ohne Ersatz.

Dies kann den Auswahlvorgang für jede 1-d-Sequenz im Tensorflow durchführen.

0
PaulG