在Tensor Flow中排队和增加变量

时间:2016-11-18 03:06:14

标签: python tensorflow

如何使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)会导致预期的行为。有人可以解释一下吗?

2 个答案:

答案 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”,这就是它的工作原理。