如何使Tensor Flow图将递增的数字推送到队列?
我只是出于学习目的这样做,所以如果你保持它与我所做的相似(并纠正我做错了),我更愿意。这是我的代码:
import tensorflow as tf
# create queue
queue = tf.RandomShuffleQueue(capacity=10, min_after_dequeue=1, dtypes=tf.float32)
# create variables, and "add" operation
push_var = tf.Variable(initial_value=1.0, trainable=False)
add = push_var.assign_add(1)
# enqueue operation
push = queue.enqueue(add)
# dequeue operation
pop = queue.dequeue()
sess = tf.InteractiveSession()
tf.initialize_all_variables().run()
# add var to stack
sess.run(push) # push_var = 2 after ran
sess.run(push) # push_var = 3 after ran
sess.run(push) # push_var = 4 after ran
sess.run(push) # push_var = 5 after ran
sess.run(push) # push_var = 6 after ran
sess.run(push) # push_var = 7 after ran
sess.run(push) # push_var = 8 after ran
# pop variable (random shuffle)
print sess.run(pop)
print sess.run(pop)
sess.close()
输出:
8
8
我希望它是2到8之间的2个随机数。相反,它总是弹出变量的当前值。
这是因为我不是推动变量的实际值而是推送指向变量的指针吗? Tensor Flow的documentation表示assign_add
返回
一个Tensor,它将在此之后保存此变量的新值 补充已经完成。
再次,我试图了解Tensor Flow。如果您有任何学习资源(除了TensorFlow网站),我感激不尽!感谢。
修改
将push = queue.enqueue(add)
更改为push = queue.enqueue(add + 0)
会导致预期的行为。有人可以解释一下吗?
答案 0 :(得分:2)
@David Wong是正确的,变量只是对其基础张量的引用。即使你已经推了7次,队列中的7个元素都指向相同的底层张量。执行pop
时,将引用并返回基础张量。
让我再解释一下。 assign_add(1)
只是更新引用的值,因此它返回一个引用。执行push = queue.enqueue(add)
时,它会在内部调用tf.convert_to_tensor(add)
,如果其输入也是引用,则会返回引用。
您可以在python shell中检查tf.convert_to_tensor(add)
的输出:
In [2]: tf.convert_to_tensor(add)
Out[2]: <tf.Tensor 'AssignAdd:0' shape=() dtype=float32_ref>
dtype=float32_ref
表示它是参考。
至于add + 0
,你也可以在ipython shell中检查它,它相当于tf.add(add, 0)
:
In [3]: add+0
Out[3]: <tf.Tensor 'add:0' shape=() dtype=float32>
它不是引用,并且具有父节点add = push_var.assign_add(1)
。
所以这里的问题是
1)当一个张量被推送到一个队列时,它将被评估,它的所有父节点也将被评估。
在您的情况下,add + 0
被评估,其父节点add = push_assign_add(1)
也将其参考值增加1。
2)推送到队列时不评估引用。队列中只有引用。当弹出并引用它们时,将获取它们的实际张量值。
在您的情况下,所有这些引用都指向相同的张量。所以弹出窗口都返回8
。
答案 1 :(得分:1)
这是因为你的“add”变量实际上是对push_var变量的引用。因此,当您推送到队列时,您正在推送对该变量的引用。按“add + 0”表示你正在推动一个新的张量,它包含“add + 0”的值,在推送时值为“add”,这就是它的工作原理。