2017-12-02 53 views
0

我想了解是否有下面的行爲可以用下面的代碼片段重現的原因。當用`sess.run`請求一個變量的值時,爲什麼沒有隱式的控制依賴?

當我請求sess.run返回Variable的值時,它返回的值不依賴於可能更新返回之前執行的變量的所有操作。

在這裏的示例中,我正在測試應用於將變量a的值複製到b之前的依賴關係,然後再爲a指定一個隨機值。

該過程有效,但第一個打印語句的結果是任意的(取決於任意處理順序),第二個打印語句的結果是正確的。

我自然希望該值張量ab返回是在所有計算的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])) 

下面的結果。請注意,ab的值在sess.run的調用之間有所不同,但它們不會更改。這表明張量流不能保證變量的返回值是返回前計算的最後一個值。

[0.0, 0.0, 0.79926836, 0.79926836, 0.0] 
[0.79926836, 0.0] 

回答

0

我認爲有兩件事需要解釋。

請記住,TensorFlow生成一個計算圖,然後sess運行它。可以這樣想:你正在定義一個循環體,然後每個調用一次迭代一次。在這種情況下,您不希望a返回op_r2a的結果 - 因爲a就像初始條件,而op_r2a就像是循環體中的更新。我認爲這解決了爲什麼沒有隱式控制依賴的好原因。

但是,你可以用tf.control_dependencies代碼塊內部迫使它(這就是爲什麼sess仍然會返回「預分配」值)。例如,定義批量規範時非常有用。但是,您的with tf.control_dependencies沒有做任何事情。您在with區塊之外分配了b <- a,並在之後分配了a <- rwith區塊內的內容不依賴於內部的內容。

我更新了你的代碼,試圖解釋這一點。

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

相關問題