TF深度理解(基礎概念的理解)
來自專欄 TensorFlow學習之路
- TensorFlow不是一個普通的庫
大多數 Python 庫被編寫為 Python 的自然擴展形式。當你導入一個庫時,你得到的時一組變數、函數和類,我們補充並擴展了你的代碼」工具箱「。使用這些庫時,你知道它們將產生怎麼樣的結果。我認為談及 TensorFlow 時應該拋棄這些認識,這些認知根本上就不符合Tensorflow 的理念,無法反映TF與其他代碼交互的方式。
Python 和 TensorFlow 之間的聯繫,可以類比 Javascript 和 HTML 之間的關係。Javascript 是一種全功能的編程語言,可以實現各種出色的效果。HTML 是用於表示某種類型的實用計算抽象(這裡指的是可由Web瀏覽器呈現的內容)的框架。Javascript在互動式網頁中的作用是組裝瀏覽器看到的 HTML對象,然後再需要時通過將其更新為新的HTML來與其交互。與 HTML 類似,TensorFlow是用於表示某種類型的計算抽象(稱為」計算圖「[Graph])的框架。當我們用 Python 操作 Tensorflow 時,我們用 Python 代碼做的第一件事是組裝計算圖。之後我們的第二個任務就是與它進行交互(使用 TensorFlow 的 」會話「[Session])。但重要的是,要記住計算圖不在變數內部,它處在全局命名空間內。」所有的RAM都是一個階段,所有的變數都只不過是指針。」
- 第一個關鍵抽象:計算圖
什麼是計算圖?它實質上是一個全局數據結構;計算圖是一個有向圖,捕獲有關計算方法的指令。
我們來看看如何構建一個示例。上半部分是我們運行的代碼,下半部分是結果計算圖。
import tensorflow as tf
import tensorflow as tftwo_node = tf.constant(2)print two_node
輸出:
Tensor("Const:0",shape=(), dtype=int32)
import tensorflow as tftwo_node = tf.constant(2)another_two_node = tf.constant(2)two_node = tf.constant(2)tf.constant(3)print(two_node)
輸出:
Tensor("Const_2:0",shape=(),dtype=int32)
相反如果創建一個新變數並將其設置為與現有節點相等,則只需將指針複製到該節點,並且不會向該圖添加任何內容:
import tensorflow as tftwo_node = tf.constant(2)another_pointer_at_two_node = two_nodetwo_node = Noneprint two_nodeprint another_pointer_at_two_node
輸出:
NoneTensor("Const:0",shape=(),dtype=int32)
更近一步:
import tensorflow as tftwo_node = tf.constant(2)three_node = tf.constant(3)sum_node = tf.add(two_node,three_node)
- 第二個關鍵抽象:會話
會話的作用是處理內存分配和優化,使我們能夠實際執行由圖形指定的計算。可以將計算圖想像為我們想要執行的計算的"模板":它列出了所有的步驟。為了使用這個圖表,我們還需要發起一個會話,它使我們能夠實際地完成任務。例如:遍歷模板的所有節點來分配一組用於儲存計算輸出的存儲器。為了使用TensorFlow進行各種計算,我們既需要圖也需要會話。
會話包含一個指向全局圖的指針,該指針通過指向所有節點的指針不斷更新。這意味著在創建之前還是之後創建會話都無所謂。創建會話對象後,可以使用sess.run(node)返回節點的值,並且TensorFlow將執行確定該值所需的所有計算。
import tensorflow as tftwo_node = tf.constant(2)three_node = tf.constant(3)sum_node = two_node + three_nodesess = tf.Session()print (sess.run(sun_node))
輸出
5
一般來說,sess.run()調用往往是最大的TensorFlow瓶頸之一,所以調用它的次數越少越好。可以的話在一個sess.run()調用中返回多個項目,而不是進行多個調用。
- 佔位符和feed_dict
我們迄今為止所做的計算一直很乏味:沒有機會獲得輸入,所以它們總是輸出相同的東西。一個實用的應用可能設計構建這樣一個計算圖:它接受輸入,以某種(一致)方式處理它,並返回一個輸出。
最直接的方法是使用佔位符。佔位符是一種用於接受外部輸入的節點。
import tensorflow as tfinput_placeholder = tf.placeholder(tf.int32)sess = tf.Session()print (sess.run(input_placeholder))
輸出將會出現錯誤:
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor Placeholder with dtype int32[[Node: Placeholder = Placeholder[dtype=DT_INT32, shape=<unknown>, _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
- 輸出的錯誤提示我們需要提供一個值,所有為了提供一個值,我們需要使用sess.run()的feed_dict屬性。
更新後的代碼
import tensorflow as tfinput_placeholder = tf.placeholder(tf.int32)sess = tf.Session()print (sess.run(input_placeholder,feed_dict={input_placeholder:2}))
輸出:
2
- 變數和副作用
到目前為止,我們已經看到兩種類型的"無祖先"節點:tf.constant(每次運行都一樣)和tf.placeholder(每次運行都不一樣)。還有第三種系欸的那:通常情況下具有相同的值,但也可以更新成新值。這個時候就要用到變數。
-了解變數對於使用TensorFlow進行深度學習來說至關重要,因為模型的參數就是變數。在訓練期間,你希望通過梯度下降在每個步驟更新參數,但在計算過程中,你希望保持參數不變,並將大量不同的測試輸入集傳入到模型中。模型所有的可訓練參數很有可能都是變數。-要創建變數,請使用 tf.get_variable() 。tf.get_variable() 的前兩個參數是必需的,其餘是可選的。它們是tf.get_variable(name,shape)。name是一個唯一標識這個變數對象的字元串。它在全局圖中必須是唯一的,所以要確保不會出現重複的名稱。shape是一個與張量形狀相似對應的整數數組,它的語法很直觀——每個維度對應一個整數,並按照排列。例如,一個 3x8 的矩陣可能具有形狀[3,8]。要創建標量,請使用空列表作為形狀:[]。
推薦閱讀:
※TFboys與區塊鏈攤上大事,王源被「安排「了
※陳奕天五一來噶舞 像極早期王源的瘋狂小舞蹈
※易烊千璽 吳磊 劉昊然 王源|95後四大流量誰的勢頭更強
※《我想和你唱》中王源最後為什麼選擇陳芃暄呢?
※青蔥少年初長成,王源說的這些話讓粉絲大呼更加被圈粉