How to sample unique number tensors from a categorical distribution in Tensorflow

Viewed 140

I would like to sample values from a categorical distribution without having duplicates in the return

I tried using tf.random.categorial but it seems that what I want to do is impossible...

tf.random.categorical(tf.math.log([[0.2,0.3,0.2,0.1,0.2]]), 4)

good result : [[3,2,4,1]] // unexpected result [[1,2,2,3]]

Currently I have solved my problem like this but the performance is very bad (10 times slower)

score_batch = tf.nn.softmax(score_batch, axis=-1)
batch_size = batch.shape[0]
indexes_array = tf.TensorArray(dtype=tf.int32, size=batch_size)
for idx in tf.range(batch_size):
    logits = tf.math.log(tf.expand_dims(score_batch[idx], axis=0))
    current_indexes = tf.random.categorical(logits, 4, dtype=tf.int32)
    current_indexes = tf.squeeze(current_indexes)
    while tf.math.not_equal(current_indexes.shape[0], tf.shape(tf.unique(current_indexes)[0])[0]):
        current_indexes = tf.random.categorical(logits, 4, dtype=tf.int32)
        current_indexes = tf.squeeze(current_indexes)
    indexes_array = indexes_array.write(idx, current_indexes)

indexes = indexes_array.stack()

UPDATE :

After testing the proposed solution works well and allows me to do what I want

1 Answers

I couldn't find a way to do it using only tensorflow, maybe it's considering that, by been prohibited of repeating classes, you are messing with the probabilities since after a class is picked, it's probability of been picked again is 0

But you can easily do it with numpy using numpy.random.choice()

numpy.random.choice(np.arange(0,5),size=4,replace=False,p=[0.2,0.3,0.2,0.1,0.2])

If you want it converted to tensor just use tf.convert_to_tensor:

tf.convert_to_tensor(numpy.random.choice(np.arange(0,5),size=4,replace=False,p=[0.2,0.3,0.2,0.1,0.2]))
Related