Effective TensorFlow Chapter7——理解執行順序和控制依賴

Effective TensorFlow Chapter7——理解執行順序和控制依賴

本文翻譯自: , 如有侵權請聯繫刪除,僅限於學術交流,請勿商用。如有謬誤,請聯繫指出。

正如我們剛開始提到的,TensorFlow不會立刻運行定義了的操作,而是在計算圖中創造一個相關的節點,這個節點可以用Session.run()進行執行。這個使得TensorFlow可以在運行時進行優化,以此確定最佳執行順序,並且在運算中剔除一些不需要使用的節點。如果你只是在計算圖中使用tf.Tensors,你就不需要擔心依賴問題,但是你更可能會使用tf.Variable(),這個操作使得問題變得更加困難。我的建議是如果張量不能滿足這個工作需求,那麼僅僅使用Variables就足夠了。這個可能不夠直觀,我們不妨先觀察一個例子:

import tensorflow as tf
a = tf.constant(1)
b = tf.constant(2)
a = a + b
tf.Session().run(a)

正如我們期待的那樣,“a”的計算結果是3。注意下,我們創建了3個張量,其中包含兩個常數張量和一個儲存加法結果的張量。務必注意我們不能重寫一個張量的值,如果我們想要改變張量的值,我們就必須要創建一個新的張量,就像我們剛才做的那樣。

小提示:如果你沒有定義一個新的計算圖,TF將會自動地為你構建一個默認的計算圖。你可以使用tf.get_default_graph()去獲得一個計算圖的句柄(handle),然後,你就可以查看這個計算圖了。比如,打印這個計算圖的所有張量:

print(tf.contrib.graph_editor.get_tensors(tf.get_default_graph()))

和 tensors 不同的是,變量Variables可以更新,所以讓我們用變量去實現我們剛才的需求:

a = tf.Variable(1)
b = tf.constant(2)
assign = tf.assign(a, a + b)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(assign))

同樣,正如預期一樣,我們又得到了3。注意到tf.assign()返回的代表這個賦值操作的張量。目前為止,所有 的操作都沒有問題,但是讓我們觀察一個稍微有點複雜的例子吧:

a = tf.Variable(1)
b = tf.constant(2)
c = a + b
assign = tf.assign(a, 5)
sess = tf.Session()
for i in range(10):
sess.run(tf.global_variables_initializer())
print(sess.run([assign, c]))

注意到,張量c並沒有一個確定性的值。這個值可能是3或者7,取決於加法和賦值操作誰先運行。

您應該注意,在代碼中定義的操作的順序與TensorFlow運行時無關。唯一會影響到執行順序的是控制依賴。控制依賴對於張量來說是直接的。每一次你在操作中使用一個張量時,操作將會定義一個對於這個張量來說的隱式的依賴。但是如果你同時也使用了變量,事情就變得更糟糕了,因為變量可以取很多值。

當處理這些變量時,你可能需要顯式地去通過使用tf.control_dependencies()去控制依賴,如:

a = tf.Variable(1)
b = tf.constant(2)
c = a + b
with tf.control_dependencies([c]):
assign = tf.assign(a, 5)
sess = tf.Session()
for i in range(10):
sess.run(tf.global_variables_initializer())
print(sess.run([assign, c]))

這會確保賦值操作在加法操作之後被調用。


分享到:


相關文章: