Tensorflow中的numpy随机选择

时间:2016-12-13 14:45:13

标签: python numpy tensorflow deep-learning

在Tensorflow中是否存在与numpy随机选择等效的函数。 在numpy中,我们可以从给定列表中随机获取一个项目及其权重。

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

此代码将使用p权重从给定列表中选择一个项目。

8 个答案:

答案 0 :(得分:17)

不,但您可以使用tf.multinomial获得相同的结果:

[0.991, 0.009] #female

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 部分在这里,因为[0][0]期望批次的每个元素都有一行非标准化的对数概率,并且还有另一个样本数量的维度。

答案 1 :(得分:2)

如果要从n维张量中随机采样行,而不是从1维张量中采样随机元素,则可以组合tf.multinomialtf.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 :(得分:2)

在tensorflow 2.0中,不建议使用tf.compat.v1.multinomial,而是使用tf.random.categorical

答案 3 :(得分:2)

聚会也很晚,我找到了最简单的解决方案。

#sample source matrix
M = tf.constant(np.arange(4*5).reshape(4,5))
N_samples = 2
tf.gather(M, tf.cast(tf.random.uniform([N_samples])*M.shape[0], tf.int32), axis=0)

答案 4 :(得分:1)

我的团队和我在将所有操作保持为tensorflow ops并实现``无替代''版本的问题上存在相同的问题。

解决方案:

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的位置将与均匀分布一样随机,因此等同于执行随机选择而不进行替换。

这可以对张量流中的任何一维序列执行选择操作。

答案 5 :(得分:1)

晚会很晚,但是我将添加另一种解决方案,因为现有的tf.multinomial方法占用了大量的临时内存,因此不能用于大量输入。这是我使用的方法(对于TF 2.0):

# Sampling k members of 1D tensor a using weights w
cum_dist = tf.math.cumsum(w)
cum_dist /= cum_dist[-1]  # to account for floating point errors
unif_samp = tf.random.uniform((k,), 0, 1)
idxs = tf.searchsorted(cum_dist, unif_samp)
samp = tf.gather(a, idxs)  # samp contains the k weighted samples

答案 6 :(得分:1)

N = np.random.choice([0,1,2,3,4], 5000, p=[i/sum(range(1,6)) for i in range(1,6)])
plt.hist(N, density=True, bins=5)
plt.grid()

enter image description here

T = tf.random.categorical(tf.math.log([[i/sum(range(1,6)) for i in range(1,6)]]), 5000)
# T = tf.random.categorical([[i/sum(range(1,6)) for i in range(1,6)]], 1000)
plt.hist(T, density=True, bins=5)
plt.grid()

enter image description here

    def random_choice(a, size):
        """Random choice from 'a' based on size without duplicates
        Args:
            a: Tensor
            size: int or shape as tuple of ints e.g., (m, n, k).
        Returns: Tensor of the shape specified with 'size' arg.

        Examples:
            X = tf.constant([[1,2,3],[4,5,6]])
            random_choice(X, (2,1,2)).numpy()
            -----
            [
              [
                [5 4]
              ],
              [
                [1 2]
              ]
            ]
        """
        if isinstance(size, int) or np.issubdtype(type(a), np.integer) or (tf.is_tensor(a) and a.shape == () and a.dtype.is_integer):
            shape = (size,)
        elif isinstance(size, tuple) and len(size) > 0:
            shape = size
        else:
            raise AssertionError(f"Unexpected size arg {size}")

        sample_size = tf.math.reduce_prod(size, axis=None)
        assert sample_size > 0

        # --------------------------------------------------------------------------------
        # Select elements from a flat array
        # --------------------------------------------------------------------------------
        a = tf.reshape(a, (-1))
        length = tf.size(a)
        assert sample_size <= length

        # --------------------------------------------------------------------------------
        # Shuffle a sequential numbers (0, ..., length-1) and take size.
        # To select 'sample_size' elements from a 1D array of shape (length,),
        # TF Indices needs to have the shape (sample_size,1) where each index
        # has shape (1,),
        # --------------------------------------------------------------------------------
        indices = tf.reshape(
            tensor=tf.random.shuffle(tf.range(0, length, dtype=tf.int32))[:sample_size],
            shape=(-1, 1)   # Convert to the shape:(sample_size,1)
        )
        return tf.reshape(tensor=tf.gather_nd(a, indices), shape=shape)

X = tf.constant([[1,2,3],[4,5,6]])
print(random_choice(X, (2,2,1)).numpy())
---
[[[5]
  [4]]

 [[2]
  [1]]]

答案 7 :(得分:-2)

在tf中无需进行随机选择。您可以直接使用np.random.choice(data,p = probs)进行操作,而tf可以接受。