我两次运行一段代码,并得到两个不同的结果
代码:
import tensorflow as tf
x = tf.placeholder(tf.int32, shape=[], name='x')
y = tf.Variable(2, dtype=tf.int32)
assign_op = tf.assign(y, y + 1)
out = x * y
with tf.control_dependencies([assign_op]):
out_ = out+2
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(3):
print('output:', sess.run(out_, feed_dict={x: 1}))
第一个输出:
output: 4
output: 5
output: 6
第二个输出:
output: 4
output: 6
output: 6
有人可以解释为什么会发生吗?
答案 0 :(得分:1)
问题是执行操作的顺序存在不确定性。 out_
始终等于out + 2
,在这种情况下,control_dependencies
块没有任何区别。问题是out
的值是多少。在某些情况下,out
会在y
更新之前进行计算,而在其他情况下,则是在更新之后进行计算,因此您可以获得4, 5, 6
,5, 6, 7
及其之间的所有内容。
如果要确保在更新{em> out
之后计算y
,可以执行以下操作:
import tensorflow as tf
x = tf.placeholder(tf.int32, shape=[], name='x')
y = tf.Variable(2, dtype=tf.int32)
y_new = tf.assign(y, y + 1) # tf.assign always returns the updated value
out = x * y_new
out_ = out + 2
这将始终打印序列5, 6, 7
。
如果要确保在更新{em> out
之前计算y
,可以执行以下操作:
import tensorflow as tf
x = tf.placeholder(tf.int32, shape=[], name='x')
y = tf.Variable(2, dtype=tf.int32)
out = x * y
with tf.control_dependencies([out]):
y_new = tf.assign(y, y + 1)
out_ = out + 2
但是,在这种情况下,评估out_
将不会更新y
(因为out_
并不取决于更新)。如果您仍然希望获得这种效果(否则您将始终在输出中得到4
),可以执行以下操作:
import tensorflow as tf
x = tf.placeholder(tf.int32, shape=[], name='x')
y = tf.Variable(2, dtype=tf.int32)
out = x * y
with tf.control_dependencies([out]):
y_new = tf.assign(y, y + 1)
# Force update y every time out is evaluated
with tf.control_dependencies([y_new]):
out = tf.identity(out)
out_ = out + 2
总是显示序列4, 5, 6
。
答案 1 :(得分:1)
Tensorflow不会像普通的python程序那样记录操作创建的顺序,而是仅跟踪其依赖关系,因此仅保证operation/op
的所有依赖关系在op
执行之前已执行。
因此,在某些情况下,out_
可以在更新y
的值之后进行更新,而在其他情况下,由于y
仅具有一个{对out_
。ie的传递依赖它取决于y
和y
变量。