У меня быстрый вопрос.Как я могу выбрать значения в {0, 1} из полиномиального распределения в TensorFlow?На самом деле мне нужна функция, которая делает то, что делает numpy.multinomial .
Предположим, например, что у меня есть вектор отсчетов и вектор вероятностей, подобный этому:
counts = [5, 4, 3] # D in my code
probs = [0.1, 0.2, 0.3, 0.1, 0.2, 0.1] # v in my code
тогда я бы хотел вернуть матрицу размером (len(counts), len(probs)) = (3, 6)
, чья сумма по каждой строке = число.
Я посмотрел на код TensorFlow и нашел способ сделать то, что я хочу.Вот мой кусок кода:
import tensorflow.contrib.distributions as ds
def multinomial_sampling(D, v):
dist = ds.Multinomial(total_count=D, probs=v)
return tf.reshape(tf.reduce_sum(dist._sample_n(1), 0 , False), [-1, v.shape[1]])
Примечание : я мог бы просто tf.expand_dims
вместо tf.reshape
Проблема заключается в том, что делать этоне занимает мало места, и когда моя матрица достаточно большая, TensorFlow просто кричит на меня, что мне не хватает памяти, потому что он пытается создать матрицу размера [1, 185929, 3390], где 3390 - длина моего вектора вероятности.
Итак, я хотел сделать свою собственную реализацию полиномиальной выборки, но я не знаю, как это сделать, и я думаю, что моя идея недостаточно эффективна (с точки зрения временной сложности).Вот мой скелет:
probsn = np.random.uniform(size=20)
probsn /= sum(probsn)
counts = tf.Variable([20, 12, 56, 3])
probs = tf.Variable(tf.convert_to_tensor(probsn))
cprobs = tf.cumsum(probs)
out = tf.zeros([tf.shape(counts)[0], tf.shape(probs)[0]])
for i in counts.shape[0]:
count = tf.gather(counts, i) # get each count
sample = tf.gather(out, i) # get each row of out
for j in range(count): # problem here count is a Tensor and not a int
rdn_number = tf.random_uniform(1)
for k, prob in enumerate(range(cprobs)): # problem doesn't work in TF
if tf.less(rdn_number, prob):
tf.scatter_add(out, [i, k], 1)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
r = sess.run(out)
print(r)
Это очень наивный алгоритм.Я думаю, что мог бы быть лучший способ уменьшить Сложность Времени (с помощью некоторого словосочетания диапазона? Который отображает диапазон значений с плавающей запятой определенным индексом в ряду? Не уверен, что такая вещь возможна, но это на самом деле позволит избежатьмне от итерации, чтобы найти индекс в моей строке ...).
Кроме того, эта реализация не работает, как упомянуто в коде, потому что число , которое я повторяю, на самом делетензор.
Есть ли у кого-нибудь аккуратная реализация многочленной выборки в TensorFlow?