使用 tf.control_dependencies 的意外(随机)执行顺序(tensorflow v1)

Unexpected (random) execution order using tf.control_dependencies (tensorflow v1)

当我 运行 以下代码 (tf v1.12.0) 时,我得到 6.0 (x->mul->ident)、7.0 (x->mul->add->ident,或9.0 (x->add->mul->ident).

有人可以解释一下为什么操作的执行顺序不受 tf.control_dependencies 控制吗?我认为至少 add_op 会在考虑控制上下文中的任何内容之前执行。

tf.reset_default_graph()

x=tf.Variable(2.0)
add_op = tf.assign_add(x, 1)
mul_op = tf.assign(x, 3*x)

with tf.control_dependencies([add_op]):
    out_op = tf.identity(mul_op)

init_op = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init_op)
    print(sess.run([out_op]))

谢谢!

这是因为mul_op不依赖于add_op。相反,out_op 依赖于 mul_op(作为显式输入)和 add_op 作为控制依赖项。在 TensorFlow 1.x 中(以及在 tf.Graph 上下文中的 TensorFlow 2.x 中),操作顺序 in Python 不影响TensorFlow 运行时.

中的操作顺序

要强制执行上述示例的确定性行为,有几个选项。

  1. 使用 add_op:
  2. tf.control_dependencies 上下文中构建 mul_op
add_op = tf.assign_add(x, 1)
with tf.control_dependencies([add_op]):
  mul_op = tf.assign(x, 3 * x)
  1. mul_op 将加法 (add_op) 的输出作为输入。
add_op = tf.assign_add(x, 1)
mul_op = tf.assign(x, 3 * add_op)
  1. 从身份操作中删除控制依赖项并在 out_opadd_op 上显式调用 sess.run()。
x=tf.Variable(2.0)
add_op = tf.assign_add(x, 1)
mul_op = tf.assign(x, 3*x)
out_op = tf.identity(mul_op)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init_op)
    sess.run(add_op)
    print(sess.run(out_op))

这些总是return9.0.

要深入真正 并查看图表中的依赖关系,您可以尝试:

tf.get_default_graph().as_graph_def()

看看图中每个节点的 input 值是什么。