這個系列主要是對TensorFlow進行學習,瞭解其內部機制、運行方法,最後能根據自己的想法構建模型。
本文主要的介紹內容是TensorFlow的Graph和Session兩個概念,即運算圖和會話。
1. 數據流圖
TensorFlow哲學:將計算圖的定義和執行分離。
階段一:運算圖的定義
階段二:使用session會話執行運算圖的操作
2. 什麼是Tensor?
Tensor是一個n維的數組
- 0-d tensor:標量,或者說數字
- 1-d tensor:向量
- 2-d tensor:矩陣
- …
讓我們看一個簡單的計算圖
在TensorBoard的模型可視化結果中,結點通常表示操作、變量以及常量;邊表示張量tensors。
這些tensor表示的是數據,TensorFlow = tensor + flow = data + flow.
從上面圖中我們可以知道,直接打印a並不能得到真正的計算結果8,這也證實了TensorFlow計算圖和執行過程確實是分離的。
那麼,我們如何才能得到計算結果a的值呢?
創建一個Session會話:在會話中可以執行運算圖,從而得到a的計算結果值(8)。具體方法就是:
import tensorflow as tf
a = tf.add(3, 5)
sess = tf.Session()
print(sess.run(a)) >> 8
sess.close()
也可以換種寫法:
import tensorflow as tf
a = tf.add(3, 5)
with tf.Session() as sess:
print(sess.run(a))
接下來,我們來看一下tf.Session()這個函數。
3. tf.Session()
tf的Session對象封裝了TF的執行環境,在環境中可以執行各種操作以及計算各種張量。此外,Session會話還將分配內存以存儲變量的當前值。
4. 更復雜的運算圖
這個運算圖完成的計算爲:。
讓我們在看一個更復雜的圖:
在這個圖中又定義了一個useless操作,但是我們希望執行的計算是z。在TF運行時,pow_op結點的計算過程並不依賴於useless,因此,會話sess在執行過程中不會執行useless的運算,這樣就可以減少不必要的運算過程。
那麼,如果我們想要同時計算useless和pow_op,應該怎麼做呢?
sess.run函數的API爲:
fetches是一個列表,其中包含我們想要執行的計算。因此,我們可以在sess.run([])列表裏添加pow_op, useless。
TensorFlow可以將運算圖分解爲幾個塊,然後在多個CPU,GPU,TPU或其他設備上並行運行它們。比如:
爲了方便劃分子塊的並行計算,我們可以指定它們的執行設備,
5. 能不能創建多個運算圖?
到目前爲止,我們只有一個運算圖,我們能不能創建多個運算圖呢?答案是可以的,但是不推薦,理由如下:
- 多個圖需要多個會話,默認情況下每個會話都會嘗試使用所有可用資源
- 如果不通過python/numpy傳遞數據,就不能在多個運算圖之間傳遞數據,而python/numpy在分佈式環境中不起作用
我們可以自己創建運算圖:
g = tf.Graph()
如果想要在默認圖中進行操作,需要執行:
g = tf.get_default_graph()
6. TF爲什麼使用Graph?
- 可以節省計算。TF可以根據輸出只運算相關的操作圖,避免執行不必要的運算
- 將計算分解爲小的微分塊,以利於自動求導
- 有利於分佈式計算。可以將運算分佈在CPU、GPU、TPU等設備上。將運算圖分解爲多個小塊,然後將小塊分散在不同的設備上,這樣有利於分佈式計算
- 許多常見的機器學習模型已經被普遍地認爲可以表示爲有向圖,這使得它們的實現對機器學習實踐者來說更加自然。