TensorFlow入門(三) TensorFlow運行模型——會話

1.3TensorFlow運行模型——會話

會話擁有並管理TensorFlow程序運行時的所有資源。當所有計算完成之後需要關閉會話來幫助系統回收資源,否則就可能出現資源泄漏的問題。TensorFlow中使用會話的模式一般有兩種,第一種模式需要明確調用會話生成函數和關閉會話函數,這種模式的代碼流程如下。

# 創建一個會話
sess = tf.Session()
# 使用這個創建好的會話來得到關心的運算的結果。比如可以調用sess.run(result),
# 來得到張量result的取值
sess.run(...)
# 關閉會話使得本次運行中使用到的資源可以被釋放
sess.close()

使用這種模式時,在所有計算完成之後,需要明確調用Session.close函數來關閉會話並釋放資源。然而,當程序因爲異常而退出時,關閉會話的函數可能就不會被執行從而導致資源泄漏。爲了解決異常退出時資源釋放的問題,TensorFlow可以通過Python上下文管理器來使用會話。以下代碼展示瞭如何使用這種模式。

# 創建一個會話,並通過python中的上下文管理器來管理這個會話
with tf.Session() as sess:
    # 使用這創建好的會話來計算關心的結果
    sess.run(...)
# 不需要再調用"Session.close"函數來關閉會話
# 當上下文退出時會話關閉和資源釋放也自動完成了

通過Python上下文管理器的機制,只要將所有的計算放在“with”的內部就可以。當上下文管理器退出時會自動釋放所有資源。這樣既解決了因爲異常退出時資源釋放的問題,同時也解決了忘記調用Session.close函數而產生的資源泄漏。

TensorFlow會自動生成一個默認的計算圖,如果沒有特殊指定,運算會自動加入這個計算圖中。TensorFlow中的會話也有類似的機制,但TensorFlow不會自動生成默認的會話,而是需要手動指定。當默認的會話被指定之後可以通過tf.Tensor.eval函數來計算一個張量的取值。以下代碼展示了通過設定默認會話計算張量的取值。

sess = tf.Session()
with sess.as_default():
    print(result.eval())

以下代碼也可以完成相同的功能。

sess = tf.Session()

# 下面的兩個命令有相同的功能
print(sess.run(result))
print(result.eval(session=sess))

在交互環境下(比如Python腳本或者Jupyter的編輯器下),通過設置默認會話的方式來獲取張量的取值更加方便。所以TensorFlow提供了一種在交互環境下直接構建默認會話的函數。這個函數就是tf.InteractiveSession。使用這個函數會自動將生成的會話註冊爲默認會話。以下代碼展示了tf.InteractiveSession函數的用法。

sess = tf.InteractiveSession()
print(result.eval())
sess.close()

通過 tf.InteractiveSession 函數可以省去將產生的會話註冊爲默認會話的過程。無論使用哪種方法都可以通過 ConfigProto Protocol Buffer 來配置需要生成的會話。下面給出了通過 ConfigProto 配置會話的方法:

config = tf.ConfigProto(allow_soft_placement=True,
                        log_device_placement=True)
sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)

通過ConfigProto可以配置類似並行的線程數、GPU分配策略、運算超時時間等參數。在這些參數中,最常使用的有兩個。第一個是allow_soft_placement,這是一個布爾型的參數,當它爲True的時候,在以下任意一個條件成立的時候,GPU上的運算可以放到CPU上進行:
1. 運算無法在GPU上執行。
2. 沒有GPU資源(比如運算被指定在第二個GPU上進行,但是計算器只有一個GPU)。
3. 運算輸入包含對CPU計算結果的引用。
這個參數的默認值爲False,但是爲了使得代碼的可移植性更強,在有GPU的環境下這個參數一般設置爲True。不同的GPU驅動版本可能對計算的支持有略微的區別,通過將allow_soft_placement參數設爲True,當某些運算無法被當前GPU支持時,可以自動調整到CPU上,而不是報錯。類似的,通過將這個參數設置爲True可以讓程序在擁有不同數量的GPU機器上順利運行。


第二個使用比較多的配置參數是log_device_placement。這是一個布爾型的參數,當它爲True時日誌中將會記錄每個節點被安排在了哪個設備上以方便調試。而在生產環境中將這個參數設置爲False可以減少日誌量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章