当用`sess.run`请求一个变量的值时,为什么没有隐式的控制依赖?
我想了解是否有下面的行为可以用下面的代码片段重现的原因。当用`sess.run`请求一个变量的值时,为什么没有隐式的控制依赖?
当我请求sess.run返回Variable的值时,它返回的值不依赖于可能更新返回之前执行的变量的所有操作。
在这里的示例中,我正在测试应用于将变量a的值复制到b之前的依赖关系,然后再为a指定一个随机值。
该过程有效,但第一个打印语句的结果是任意的(取决于任意处理顺序),第二个打印语句的结果是正确的。
我自然希望该值张量a和b返回是在所有计算的END变量的值,但事实并非如此。
不是是否有一个很好的理由,包括对作为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的调用之间有所不同,但它们不会更改。这表明张量流不能保证变量的返回值是返回前计算的最后一个值。
[0.0, 0.0, 0.79926836, 0.79926836, 0.0] [0.79926836, 0.0] 
回答:
我认为有两件事需要解释。
请记住,TensorFlow生成一个计算图,然后sess运行它。可以这样想:你正在定义一个循环体,然后每个调用一次迭代一次。在这种情况下,您不希望a返回op_r2a的结果 - 因为a就像初始条件,而op_r2a就像是循环体中的更新。我认为这解决了为什么没有隐式控制依赖的好原因。
但是,你可以用tf.control_dependencies代码块内部迫使它(这就是为什么sess仍然会返回“预分配”值)。例如,定义批量规范时非常有用。但是,您的with tf.control_dependencies没有做任何事情。您在with区块之外分配了b <- a,并在之后分配了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退出with块。也就是说,update_b依赖于update_a更改a的值,但tf.Variable(0.0)的值保持不变,直到下一次呼叫sess.run。
以上是 当用`sess.run`请求一个变量的值时,为什么没有隐式的控制依赖? 的全部内容, 来源链接: utcz.com/qa/258855.html

