请参见代码段:
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>
有两种可能的结果:
它们取决于求值顺序,对于第一种情况,import tensorflow as tf
x = tf.Variable(1)
op = tf.assign(x, x + 1)
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run([x, op]))
在x
之前进行评估,对于第二种情况,op
在x
之后进行评估。
我已经多次运行代码,但是结果始终是op
。因此,我猜想x=2 and op=2
可以保证tensorflow
之后得到x
的求值。这样对吗? op
如何保证依赖性?
对于上述情况,结果是确定的。但是在以下情况下,结果并不确定。
tensorflow
在第一个代码中,import tensorflow as tf
x = tf.Variable(1)
op = tf.assign(x, x + 1)
x = x + 0 # add this line
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(5):
print(sess.run([x, op]))
是x
,而Variable
取决于op
,因此x
总是在x
之后求值。但是在第二种情况下,op
变为x
,并且Tensor
依赖于op
(在Variable x
之后,x被覆盖)。因此x = x + 0
不依赖于op
。
答案 0 :(得分:2)
张量的求值顺序不确定。请参阅the API docs(在&&&
上“返回”信息的最底部)。因此,您不应依赖于它们以特定顺序执行。如果需要保证订单,则可能应该对不同的张量/运算使用单独的Session.run()
调用。
答案 1 :(得分:0)
这有效:
with tf.device('/cpu:0'):
# x = tf.get_variable('x', shape=(), initializer=tf.constant_initializer(1), dtype=tf.int32)
x = tf.Variable(1)
op = tf.assign(x, x+1)
with tf.control_dependencies([op]):
x = x + 0
# x = tf.multiply(x, 3)
# x = tf.add(x, 0)
但并非总是如此:
with tf.device('/cpu:0'):
# x = tf.get_variable('x', shape=(), initializer=tf.constant_initializer(1), dtype=tf.int32)
x = tf.Variable(1)
with tf.device('/gpu:0'): # add this line.
op = tf.assign(x, x+1)
with tf.control_dependencies([op]):
x = x + 0
# x = tf.multiply(x, 3)
# x = tf.add(x, 0)
我认为问题出在:
某些操作(例如x = x + 0
,从Variable
读取值然后加0)取决于Variable
的值,而Variable
通过某些分配操作(例如op = tf.assign(x,x + 1))进行更改。如果没有依赖性,则这两个操作是并行的。因此,在读取Variable
的值时,不确定assign
是否已经完成。
从不同设备传输数据。即使存在依赖关系,也仍然不确定。
简而言之,如果所有变量和操作都在同一设备中,则with tf.control_dependencies
should guarantee的op在添加操作之前。
请注意:
(以下注释并不重要,但可能会对您有所帮助)
tf.assign
操作仅更新Variable
,而不更新Tensor
。
执行x=x+0
时,新的x
变成Tensor
;但是op = tf.assign(x, x+1)
返回Variable
的引用。因此,op
应该始终是确定的,因为它取决于Variable
的当前值,该值不会被其他操作更改。
GPU不支持int32变量。当我在计算机(tf-gpu1.12)上运行您的代码段时,会在CPU上创建变量,而在GPU上进行操作。您可以通过config = tf.ConfigProto(log_device_placement=True)
检查变量和操作。