首先,我不确定标题是否非常好,但鉴于我对情况的理解,这是我能想到的最好的。
背景是我正在试图了解队列中的队列是如何工作的,并遇到了困扰我的以下问题。
我有一个变量 n ,我将其排入 tf.FIFOQueue ,然后我增加变量。这会重复几次,人们会期望结果类似于0,1,2 ......但是,当清空队列时,所有值都是相同的。
更准确地说,代码如下:
from __future__ import print_function
import tensorflow as tf
q = tf.FIFOQueue(10, tf.float32)
n = tf.Variable(0, trainable=False, dtype=tf.float32)
inc = n.assign(n+1)
enqueue = q.enqueue(n)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
sess.run(enqueue)
sess.run(inc)
sess.run(enqueue)
sess.run(inc)
sess.run(enqueue)
sess.run(inc)
print(sess.run(q.dequeue()))
print(sess.run(q.dequeue()))
print(sess.run(q.dequeue()))
我希望打印出来:
0.0
1.0
2.0
相反,我得到以下结果:
3.0
3.0
3.0
好像我正在向队列推送一些指向n的指针,而不是实际值,这就是我想要的。但是,我对tensorflow内部结构没有任何实际的了解,所以也许还有其他事情发生了?
我尝试过更改
enqueue = q.enqueue(n)
到
enqueue = q.enqueue(tf.identity(n))
因为对How can I copy a variable in tensorflow和In TensorFlow, what is tf.identity used for?的回答给我的印象是它可能会有所帮助,但它不会改变结果。我也尝试添加一个tf.control_dependencies(),但同样,所有值在出列时都是相同的。
编辑:上面的输出来自在单个CPU的计算机上运行代码,当试图查看不同版本的tensorflow之间是否存在某些差异时,我注意到我是否在具有CPU和GPU的计算机上运行代码我得到了“预期”的结果。实际上,如果我使用CUDA_VISIBLE_DEVICES =“”运行,我得到上面的结果,并且使用CUDA_VISIBLE_DEVICES =“0”我得到“预期”结果。
答案 0 :(得分:3)
要强制进行非缓存读取,您可以执行
q.enqueue(tf.add(q, 0))
这是批量规范化层强制复制的currently done。
变量如何被读取和被引用的语义正在进行修改,因此它们暂时不直观。特别是,我希望q.enqueue(v.read_value())
强制进行非缓存读取,但它并没有修复你在TF 0.12rc1上的例子
使用GPU机器将变量置于GPU上,而Queue仅为CPU,因此enqueue
op强制执行GPU-> CPU复制。
答案 1 :(得分:0)
如果它有帮助,我发现其他答案尽管正确但它们并不适用于所有dtypes。
例如,这适用于浮点数或整数但是当n是字符串张量时失败:
q.enqueue(tf.add(n, 0))
当队列使用具有异构类型的元组(例如,整数和浮点数)时,这个失败:
q.enqueue_many([[n]])
所以,如果您发现自己遇到任何这些情况,请尝试这样做:
q.enqueue(tf.add(n, tf.zeros_like(n)))
或者,将元组排入队列 t :
q.enqueue([tf.add(n, tf.zeros_like(n)) for n in t])
即使对于字符串张量和异构元组类型也是如此。
希望它有所帮助!
-
更新:看起来tf.bool类型不适用于tf.zeros_like()。对于那些,可能需要显式转换为整数类型。