入队时强制复制张量

时间:2016-12-23 22:30:39

标签: tensorflow

首先,我不确定标题是否非常好,但鉴于我对情况的理解,这是我能想到的最好的。

背景是我正在试图了解队列中的队列是如何工作的,并遇到了困扰我的以下问题。

我有一个变量 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 tensorflowIn TensorFlow, what is tf.identity used for?的回答给我的印象是它可能会有所帮助,但它不会改变结果。我也尝试添加一个tf.control_dependencies(),但同样,所有值在出列时都是相同的。

编辑:上面的输出来自在单个CPU的计算机上运行代码,当试图查看不同版本的tensorflow之间是否存在某些差异时,我注意到我是否在具有CPU和GPU的计算机上运行代码我得到了“预期”的结果。实际上,如果我使用CUDA_VISIBLE_DEVICES =“”运行,我得到上面的结果,并且使用CUDA_VISIBLE_DEVICES =“0”我得到“预期”结果。

2 个答案:

答案 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()。对于那些,可能需要显式转换为整数类型。