@David Wong 是正确的,该变量只是对其基础张量的引用。即使您已经推送了 7 次,队列中的 7 个元素都指向相同的底层张量。什么时候pop
执行后,底层张量被引用并返回。
让我再解释一下。这assign_add(1)
只是更新引用的值,因此它返回一个引用。当你这样做时push = queue.enqueue(add)
,它内部调用tf.convert_to_tensor(add) https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/data_flow_ops.py#L276如果它的输入也是一个引用,它将返回一个引用。
您可以检查输出tf.convert_to_tensor(add)
在Python外壳中:
In [2]: tf.convert_to_tensor(add)
Out[2]: <tf.Tensor 'AssignAdd:0' shape=() dtype=float32_ref>
The dtype=float32_ref
表明它是一个参考。
As for 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
.