web-dev-qa-db-ja.com

Tensorflowのnumpyランダム選択

Tensorflowのnumpyランダム選択と同等の機能はありますか? numpyでは、指定されたリストから重み付きでアイテムをランダムに取得できます。

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

このコードは、指定されたリストからp個の重みを持つアイテムを選択します。

21
seleucia

いいえ、ただし 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

multinomialはバッチの各要素の正規化されていないログ確率の行を期待し、サンプル数の別の次元も持っているため、[0][0]部分はここにあります。

18
sygi

1次元のテンソルからランダムな要素をサンプリングする代わりに、n次元のテンソルからランダムに行をサンプリングする場合は、tf.multinomialおよび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

私のチームと私は、すべての操作をテンソルフロー操作として保持し、「置換なし」バージョンを実装するという要件に関して同じ問題を抱えていました。

解決:

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

このコードの背後にある考え方は、選択の選択を実行するベクトルの次元に等しい次元を持つランダムな一様分布を生成することです。分布は一意でランク付け可能な一連の数値を生成するため、上位kポジションのインデックスを取得し、それらを選択として使用できます。トップkの位置は一様分布と同じくらいランダムになるため、置換なしでランダムに選択することになります。

これにより、テンソルフローの任意の1次元シーケンスで選択操作を実行できます。

1
PaulG