我認爲有兩件事需要解釋。
請記住,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
。