张量流会话运行张量列表的顺序是什么?

时间:2018-12-11 13:49:59

标签: python tensorflow

请参见代码段:

<webHttp helpEnabled="true"  automaticFormatSelectionEnabled="true"/> 

有两种可能的结果:

  • x = 1和op = 2
  • x = 2和op = 2

它们取决于求值顺序,对于第一种情况,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之前进行评估,对于第二种情况,opx之后进行评估。

我已经多次运行代码,但是结果始终是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

2 个答案:

答案 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)

我认为问题出在:

  1. 某些操作(例如x = x + 0,从Variable 读取值然后加0)取决于Variable的值,而Variable通过某些分配操作(例如op = tf.assign(x,x + 1))进行更改。如果没有依赖性,则这两个操作是并行的。因此,在读取Variable的值时,不确定assign是否已经完成。

  2. 从不同设备传输数据。即使存在依赖关系,也仍然不确定。

简而言之,如果所有变量和操作都在同一设备中,则with tf.control_dependencies should guarantee的op在添加操作之前。

请注意:

(以下注释并不重要,但可能会对您有所帮助)

  1. tf.assign操作仅更新Variable,而不更新Tensor

  2. 执行x=x+0时,新的x变成Tensor;但是op = tf.assign(x, x+1)返回Variable的引用。因此,op应该始终是确定的,因为它取决于Variable的当前值,该值不会被其他操作更改。

  3. GPU不支持int32变量。当我在计算机(tf-gpu1.12)上运行您的代码段时,会在CPU上创建变量,而在GPU上进行操作。您可以通过config = tf.ConfigProto(log_device_placement=True)检查变量和操作。