我一直以为变量赋值是在给sess.run的列表中的所有操作之后完成的,但是下面的代码在不同的执行中返回不同的结果。似乎随机运行列表中的操作并在列表中的操作运行后分配变量。
a = tf.Variable(0)
b = tf.Variable(1)
c = tf.Variable(1)
update_a = tf.assign(a, b + c)
update_b = tf.assign(b, c + a)
update_c = tf.assign(c, a + b)
with tf.Session() as sess:
sess.run(initialize_all_variables)
for i in range(5):
a_, b_, c_ = sess.run([update_a, update_b, update_c])
我想知道变量赋值的时间。 哪些是正确的:“update_x -> assign x -> ... -> udpate_z -> assign z”或“update_x -> udpate_y -> udpate_z -> assign a, b, c”? (其中 (x, y, z) 是 (a, b, c) 的排列) 另外,如果有后一种赋值的实现方法(链表中的所有操作完成后赋值),请告诉我如何实现。
最佳答案
update_a
、update_b
和update_c
这三个操作在数据流图中没有相互依赖关系,因此 TensorFlow 可以选择以任何方式执行它们命令。 (在当前的实现中,它们三个都可能在不同的线程上并行执行。)第二个问题是默认情况下会缓存变量的读取,因此在您的程序中, update_b< 中分配的值
(即 c + a
)可能会使用 a
的原始值或更新后的值,具体取决于首次读取变量的时间。
如果要确保操作按特定顺序发生,可以使用 with tf.control_dependencies([...]):
block 以强制在 block 中创建的操作发生在列表中命名的操作之后。您可以使用 tf.Variable.read_value()
在 with tf.control_dependencies([...]):
block 中,明确读取变量的点。
因此,如果你想确保 update_a
发生在 update_b
之前并且 update_b
发生在 update_c
之前,你可以这样做:
update_a = tf.assign(a, b + c)
with tf.control_dependencies([update_a]):
update_b = tf.assign(b, c + a.read_value())
with tf.control_dependencies([update_b]):
update_c = tf.assign(c, a.read_value() + b.read_value())
关于python - Tensorflow:什么时候在 sess.run 中用列表完成变量赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41288713/