我想了解以下行为是否有理由可以使用下面的代码段重现。
当我请求sess.run
返回Variable
的值时,它返回的值不依赖于在返回之前可能更新正在执行的变量的所有操作。
在这里的示例中,我正在测试应用于将变量a
的值复制到b
中的依赖项,然后使用随机值重新分配a
。
该过程有效,但第一个print语句的结果是任意的(取决于任意处理顺序),第二个print语句的结果是正确的。
我自然希望张量a
和b
返回的值是所有计算的 END 的变量值,但事实并非如此。
NOT 是否有充分的理由包括对作为sess.run
一部分请求的变量的隐式控制依赖?
import tensorflow as tf
a = tf.Variable(0.0)
b = tf.Variable(0.0)
r = tf.random_normal(shape=())
op_a2b = tf.assign(b, a)
with tf.control_dependencies([op_a2b]):
op_r2a = tf.assign(a, r)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
print(sess.run([a, b, r, op_r2a, op_a2b]))
print(sess.run([a, b]))
以下结果。请注意,a
和b
的值在sess.run
的调用之间有所不同,尽管它们不会更改。这表明tensorflow不保证变量的返回值是返回之前计算的最后一个东西。
[0.0, 0.0, 0.79926836, 0.79926836, 0.0]
[0.79926836, 0.0]
答案 0 :(得分:0)
我认为有两件事需要解释。
请记住,TensorFlow会构建一个计算图,然后sess
运行它。可以这样想:你定义一个循环体,然后sess
每次调用迭代一次。在这种情况下,您不会期望a
返回op_r2a
的结果 - 因为a
就像一个初始条件而op_r2a
就像是一个更新循环体。我认为,这就解决了为什么没有隐含的控制依赖性的充分理由。
但是,您可以在代码块中强制使用tf.control_dependencies
(这就是sess
仍然会返回"预分配&#的原因34;价值)。例如,在定义批量规范时它很有用。但是,您的with tf.control_dependencies
并未做任何事情。您在b <- a
块之外分配with
,然后分配a <- r
。 with
区块内的内容并不取决于外面的内容。
我更新了您的代码,试图解释一下。
import tensorflow as tf
# Define a graph, a_t <- r_{t-1}; b_t <- a_t
a = tf.Variable(0.0)
b = tf.Variable(1.0)
r = tf.random_normal(shape=())
update_a = tf.assign(a, r)
with tf.control_dependencies([update_a]):
# JUST to illustrate tf.control_dependencies,
# make `a` take the value of `update_a`.
update_b = tf.assign(b, a)
update_b_differently = tf.assign(b, update_a)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
# Run it
print("Timestep 1:")
a0, b0, r1, a1, b1, bx = sess.run([a, b, r, update_a, update_b,
update_b_differently])
print("a_0 =", a0, "--> a_1 =", a1, "(= r_1 =", r1, ")")
print("b_0 =", b0, "--> b_1 =", b1, "(= a_1 =", a1, ")")
print("update_b =", b1, "= update_b_differently =", bx)
print("\nTimestep 2 (Don't step up, just check initial conditions)")
a1_again, b1_again = sess.run([a, b])
print("a_1 =", a1_again, "is the initial condition for T.S. 2")
print("b_1 =", b1_again, "is the initial condition for T.S. 2")
输出
Timestep 1:
a_0 = 0.0 --> a_1 = 0.0190619 (= r_1 = 0.0190619 )
b_0 = 1.0 --> b_1 = 0.0190619 (= a_1 = 0.0190619 )
update_b = 0.0190619 = update_b_differently = 0.0190619
Timestep 2 (Don't step up, just check initial conditions)
a_1 = 0.0190619 is the initial condition for T.S. 2
b_1 = 0.0190619 is the initial condition for T.S. 2
请注意,我们已分配给tf.Variable(0.0)
并使用tf.control_dependencies
在分配给update_b
时使其保持不变,但sess.run(a)
仍然返回0.但是,a
的新值当update_b
退出update_b
时,{1}}会与with
保持一致。也就是说,update_b
取决于update_a
更改a
的值,但tf.Variable(0.0)
的值在下次调用sess.run
之前保持不变。< / p>