TensorFlow是什么?怎么用?终于有人讲明白了
導讀:在開始使用TensorFlow之前,必須了解它背后的理念。該庫很大程度上基于計算圖的概念,除非了解它們是如何工作的,否則無法理解如何使用該庫。本文將簡要介紹計算圖,并展示如何使用TensorFlow實現簡單計算。
作者:翁貝托·米凱盧奇(Umberto Michelucci)
來源:大數據DT(ID:bigdatadt)
01 計算圖
要了解TensorFlow的工作原理,必須了解計算圖是什么。計算圖是一幅圖,其中每個節點對應于一個操作或一個變量。變量可以將其值輸入操作,操作可以將其結果輸入其他操作。
通常,節點被繪制為圓圈,其內部包含變量名或操作,當一個節點的值是另一個節點的輸入時,箭頭從一個節點指向另一個節點。可以存在的最簡單的圖是只有單個節點的圖,節點中只有一個變量。(請記住,節點可以是變量或操作。)圖1-16中的圖只是計算變量x的值。
▲圖1-16 我們可以構建的最簡單的圖,它表示一個簡單的變量
現在讓我們考慮稍微復雜的圖,例如兩個變量x和y之和(z=x+y),如圖1-17所示。
▲圖1-17 兩個變量之和的基本計算圖
圖1-17左側的節點(圈里有x和y的節點)是變量,而較大的節點表示兩個變量之和。箭頭表示兩個變量x和y是第三個節點的輸入。應該以拓撲順序讀取(和計算)圖,這意味著你應該按照箭頭指示的順序來計算不同的節點。箭頭還會告訴你節點之間的依賴關系。要計算z,首先必須計算x和y。也可以說執行求和的節點依賴于輸入節點。
要理解的一個重要方面是,這樣的圖僅定義了對兩個輸入值(在這里為x和y)執行什么操作(在這里為求和)以獲得結果(在這里為z)。它基本上定義了“如何”。你必須為x和y這兩個輸入都賦值,才能執行求和以獲得z。只有在計算了所有的節點后,圖才會顯示結果。
注釋:在本書中,圖的“構造”階段是指在定義每個節點正在做什么時,“計算”階段是指當我們實際計算相關操作時。
這是需要了解的一個非常重要的方面。請注意,輸入變量不一定是實數,它們可以是矩陣、向量等。(本書中主要使用矩陣。)在圖1-18中可以找到稍微復雜的示例,即給定三個輸入量x、y和A,使用圖計算A(x+y)的值。
▲圖1-18 給定三個輸入量x、y和A,計算A(x+y)的值的計算圖
可以通過為輸入節點(在本例中為x、y和A)賦值來計算此圖,并通過圖計算節點。例如,如果采用圖1-18中的圖并賦值x=1、y=3和A=5,將得到結果b=20(如圖1-19所示)。
▲圖1-19 要計算圖1-18中的圖,必須為輸入節點x、y和A賦值,然后通過圖計算節點
神經網絡基本上是一個非常復雜的計算圖,其中每個神經元由圖中的幾個節點組成,這些節點將它們的輸出饋送到一定數量的其他神經元,直到到達某個輸出。
TensorFlow可以幫助你非常輕松地構建非常復雜的計算圖。通過構造,可以將評估計算與構造進行分離。(請記住,要計算結果,必須賦值并計算所有節點。)
注釋:請記住,TensorFlow首先構建一個計算圖(在所謂的構造階段),但不會自動計算它。該庫將兩個步驟分開,以便使用不同的輸入多次計算圖形。
02 張量
TensorFlow處理的基本數據單元是張量(Tensor),它包含在TensorFlow這個單詞中。張量僅僅是一個形為n維數組的基本類型(例如,浮點數)的集合。以下是張量的一些示例(包括相關的Python定義):
-
1→一個純量
-
[1,2,3]→一個向量
-
[[1,2,3], [4,5,6]]→一個矩陣或二維數組
張量具有靜態類型和動態維度。在計算它時,不能更改其類型,但可以在計算之前動態更改維度。(基本上,聲明張量時可以不指定維度,TensorFlow將根據輸入值推斷維度。)通常,用張量的階(rank)來表示張量的維度數(純量的階可以認為是0)。表1-1可以幫助理解張量的不同階。
| 階 | 數學實體 | Python例子 |
| 0 | 純量(例如,長度或重量) | L=30 |
| 1 | 張量(例如,二維平面中物體的速度) | S=[10.2,12.6] |
| 2 | 矩陣 | M=[[23.2,44.2],[12.2,55.6]] |
| 3 | 3D矩陣(帶有三個維度) | C=[[[1],[2]],[[3],[4]],[[5],[6]]] |
▲表1-1 階為0、1、2和3的張量示例
假設你使用語句import TensorFlow as tf導入TensorFlow,則基本對象(張量)是類tf.tensor。tf.tensor有兩個屬性:
-
數據類型 (例如,float32)
-
形狀(例如,[2,3]表示這是一個2行3列的張量)
一個重要的方面是張量的每個元素總是具有相同的數據類型,而形狀不需要在聲明時定義。主要張量類型(還有更多)有:
-
tf.Variable
-
tf.constant
-
tf.placeholder
tf.constant和tf.placeholder值在單個會話運行期間(稍后會詳細介紹)是不可變的。一旦它們有了值,就不會改變。例如,tf.placeholder可以包含要用于訓練神經網絡的數據集,一旦賦值,它就不會在計算階段發生變化。
tf.Variable可以包含神經網絡的權重,它們會在訓練期間改變,以便為特定問題找到最佳值。最后,tf.constant永遠不會改變。我將在下一節展示如何使用這三種不同類型的張量,以及在開發模型時應該考慮哪些方面。
03 創建和運行計算圖
下面開始使用TensorFlow來創建計算圖。
注釋:請記住,我們始終將構建階段(定義圖應該做什么)與它的計算階段(執行計算)分開。TensorFlow遵循相同的理念:首先構建一個圖形,然后進行計算。
考慮非常簡單的事情:對兩個張量求和,即
x1+x2
可以使用圖1-20的計算圖來執行計算。
▲圖1-20 求兩個張量之和的計算圖
04 包含tf.constant的計算圖
如前所述,首先必須使用TensorFlow創建這個計算圖。(記住,我們從構建階段開始。)讓我們開始使用tf.constant張量類型。我們需要三個節點:兩個用于輸入變量,一個用于求和。可以通過以下代碼實現:
x1?=?tf.constant(1)? x2?=?tf.constant(2)? z?=?tf.add(x1,?x2)以上代碼創建圖1-20中的計算圖,同時,它告訴TensorFlow:x1的值是1(聲明中括號內的值),而x2的值為2。現在,要執行代碼,我們必須創建被TensorFlow稱為會話的過程(實際的計算過程就在其中進行),然后可以請求會話類通過以下代碼運行我們的圖:
sess?=?tf.Session()? print(sess.run(z))這將簡單地提供z的計算結果,正如所料,結果是3。這部分代碼相當簡單且不需要太多,但不是很靈活。例如,x1和x2是固定的,并且在計算期間不能改變。
注釋:在TensorFlow中,首先必須創建計算圖,然后創建會話,最后運行圖。必須始終遵循這三個步驟來計算你的圖。
請記住,也可以要求TensorFlow僅計算中間步驟。例如,你可能想要計算x1,比如sess.run(x1)(雖然在這個例子中沒什么意義,但是在很多情況下它很有用,例如,如果想要在評估圖的同時評估模型的準確性和損失函數)。
你會得到結果1,正如預期的那樣。最后,請記住使用sess.close()關閉會話以釋放所用資源。
05 包含tf.Variable的計算圖
可以使用相同的計算圖(圖1-20中的圖)來創建變量,但這樣做有點麻煩,不如讓我們重新創建計算圖。
x1?=?tf.Variable(1)? x2?=?tf.Variable(2)? z?=?tf.add(x1,x2)我們像之前一樣用值1和2進行變量初始化。問題在于,當使用以下代碼運行此圖時,將收到一條報錯消息。
sess?=?tf.Session() print(sess.run(z))這是一條非常長的消息,但消息的結尾包含以下內容:
發生這種情況是因為TensorFlow不會自動初始化變量。為此,你可以使用此辦法:
sess?=?tf.Session()? sess.run(x1.initializer)? sess.run(x2.initializer)? print(sess.run(z))現在沒有錯誤了。sess.run(x1.initializer)這行代碼將使用值1初始化變量x1,而sess.run(x2.initializer)將使用值2初始化變量x2,但這相當麻煩。(你也不希望為每個需要初始化的變量寫一行代碼。)更好的方法是在計算圖中添加一個節點,以便使用如下代碼初始化在圖中定義的所有變量:
init?=?tf.global_variables_initializer()然后再次創建并運行會話,并在計算z之前運行此節點(init)。
sess?=?tf.Session()? sess.run(init)? print(sess.run(z))? sess.close()以上代碼很有效,如你所料,輸出了正確結果3。
注釋:使用變量時,請記住一定要添加全局初始化器(tf.global_variables_initializer()),并在一開始就在會話中運行該節點,然后再進行任何其他計算。我們將在本書的許多例子中看到它是如何工作的。
06 包含tf. placeholder的計算圖
我們將x1和x2聲明為占位符:
x1?=?tf.placeholder(tf.float32,?1)? x2?=?tf.placeholder(tf.float32,?1)請注意,我沒有在聲明中提供任何值。我們將不得不在計算時為x1和x2賦值。這是占位符與其他兩種張量類型的主要區別。然后,再次用以下代碼執行求和:
z?=?tf.add(x1,x2)請注意,如果嘗試查看z中的內容,例如print(z),你將得到:
為何得到這個奇怪的結果?首先,我們沒有給TensorFlow提供x1和x2的值,其次,TensorFlow還沒有運行任何計算。請記住,圖的構造和計算是相互獨立的步驟。現在我們像之前一樣在TensorFlow中創建一個會話。
sess?=?tf.Session()現在可以運行實際的計算了,但要做到這一點,必須先為x1和x2兩個輸入賦值。這可以通過使用一個包含所有占位符的名稱作為鍵的Python字典來實現,并為這些鍵賦值。在此示例中,我們將值1賦給x1,將值2賦給x2。
feed_dict={?x1:?[1],?x2:?[2]}可以通過使用以下命令將上面的代碼提供給TensorFlow會話:
print(sess.run(z,?feed_dict))終于得到了期望的結果:3。注意,TensorFlow相當聰明,可以處理更復雜的輸入。讓我們重新定義占位符,以便使用包含兩個元素的數組。(在這里,我們給出完整的代碼,以便更容易跟進該示例。)
x1?=?tf.placeholder(tf.float32,?[2])? x2?=?tf.placeholder(tf.float32,?[2]) z?=?tf.add(x1,x2)? feed_dict={?x1:?[1,5],?x2:?[1,1]} sess?=?tf.Session()? sess.run(z,?feed_dict)這次,將得到一個包含兩個元素的數組作為輸出。
請記住,x1=[1,5]和x2=[1,1]意味著z=x1+x2=[1,5]+[1,1]=[2,6],因為求和(sum)是對數組中逐元素求和得到的。
總結一下,下面是一些關于何時使用哪種張量類型的指南:
-
對于在計算階段不發生更改的實體,請使用tf.placeholder。通常,它們是你希望在計算期間保持固定不變的輸入值或參數,但可能隨每次運行而變化。(你將在本書后面看到幾個示例。)示例包括輸入數據集、學習率等。
-
對于在計算過程中會發生變化的實體,請使用tf.Variable,例如,神經網絡的權重,本書后面將對此進行介紹。
-
tf.constant用于永不更改的實體,例如,那些在模型中不再更改的固定值。
圖1-21描繪了一個稍微復雜的例子:計算x1w1+x2w2的計算圖。
▲圖1-21 計算x1w1+x2w2的計算圖
在這個例子中,我將x1、x2、w1和w2定義為包含純量的占位符(它們將是輸入)(記住:在定義占位符時,必須始終將維度作為第二個輸入參數傳入,在本例中是1)。
x1?=?tf.placeholder(tf.float32,?1)? w1?=?tf.placeholder(tf.float32,?1)? x2?=?tf.placeholder(tf.float32,?1)? w2?=?tf.placeholder(tf.float32,?1) z1?=?tf.multiply(x1,w1)? z2?=?tf.multiply(x2,w2)? z3?=?tf.add(z1,z2)運行該計算也就意味著(如前所述):定義包含輸入值的字典,之后創建會話,然后運行它。
feed_dict={?x1:?[1],?w1:[2],?x2:[3],?w2:[4]}? sess?=?tf.Session()? sess.run(z3,?feed_dict)不出所料,你將獲得以下結果:
這很簡單,即1×2+3×4=2+12=14(記住,在前一步驟中已經在feed_dict中輸入了值1、2、3和4)。與往常一樣,請記得在完成后用sess.close()關閉會話。
注釋:在TensorFlow中,可能會發生同一段代碼運行多次,并且最終會得到一個包含同一節點的多個副本的計算圖。避免此類問題的一種非常常見的方法是在運行構造該圖的代碼之前先運行代碼tf.reset_default_graph()。請注意,如果你將構造代碼與計算代碼恰當地分開了,則應該能夠避免此類問題。我們將在本書后面的許多例子中看到它是如何工作的。
關于作者:翁貝托·米凱盧奇(Umberto Michelucci),目前在瑞士領先的醫療保險公司從事創新和人工智能(AI)工作。他領導與人工智能、新技術、機器學習以及大學的研究合作相關的多項戰略計劃。此前,他曾擔任多個大型醫療保健項目的數據科學家和首席建模師,并在編程和算法設計方面擁有豐富的實踐經驗。他管理過商務智能和數據倉庫項目,使數據驅動的解決方案能夠在復雜的生產環境中實施。
本文摘編自《深度學習:基于案例理解深度神經網絡》,經出版方授權發布。
延伸閱讀《深度學習:基于案例理解深度神經網絡》
點擊上圖了解及購買
轉載請聯系微信:DoctorData
推薦語:本書探討了深度學習中的高級主題,例如優化算法、超參數調整、Dropout和誤差分析,以及解決在訓練深度神經網絡時遇到的典型問題的策略。你首先要研究激活函數,主要是單個神經元(relu、sigmoid和swish),了解如何使用TensorFlow進行線性和邏輯回歸,并選擇正確的代價函數。
有話要說????
Q:?你用TensorFlow做什么?
歡迎留言與大家分享
猜你想看????
-
吐血整理!萬字原創讀書筆記,數據分析的知識點全在這里了
-
8本書,玩轉這個2019年突然爆火的概念
-
Python、數據分析、機器學習、區塊鏈大牛在偷偷看的9本書
-
DNA配對找對象?為了讓年輕人結婚生孩子,日本有多拼?
更多精彩????
在公眾號對話框輸入以下關鍵詞
查看更多優質內容!
PPT?|?報告?|?讀書?|?書單?|?干貨?
大數據?|?揭秘?|?Python?|?可視化
AI?|?人工智能?|?5G?|?中臺
機器學習?|?深度學習?|?神經網絡
合伙人?|?1024?|?段子?|?數學
據統計,99%的大咖都完成了這個神操作
????
覺得不錯,請把這篇文章分享給你的朋友
轉載 / 投稿請聯系:baiyu@hzbook.com
更多精彩,請在后臺點擊“歷史文章”查看
點擊閱讀原文,了解更多
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的TensorFlow是什么?怎么用?终于有人讲明白了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python代码实操:详解数据清洗
- 下一篇: 数据中台必备的4个核心能力,你让数据创造