當前位置:
首頁 > 知識 > 20分鐘了解TensorFlow基礎

20分鐘了解TensorFlow基礎

本文為 AI 研習社編譯的技術博客,原標題 :

Learn TensorFlow Fundamentals in 20 Minutes

作者 |Chidume Nnamdi

翻譯 | linlh、餘杭、通夜 編輯 | 王立魚、約翰遜·李加薪

https://blog.bitsrc.io/learn-tensorflow-fundamentals-in-20-minutes-cdef2dec331a

介紹:TensorFlow是一個由Google創建的開源軟體庫,用於實現機器學習和深度學習系統。

這兩個名字包含一系列共同挑戰的強大演算法 - 使得計算機學習如何自動發現複雜模式和/或做出最佳決策。

TensorFlow:現代化的機器學習庫

TensorFlow,由Google在2015年11月面向公眾開源,是從創建和使用其前身DistBelief中吸取多年的經驗的結果。

它設計為靈活,高效,可擴展,輕便。任何形狀和大小的計算機都可以運行它,從智能手機一路支持到大型計算集群。它配備了輕量級的軟體,可以即時生成訓練好的模型,有效地消除了重新實現模型的麻煩。

TensorFlow包含開源的創新和社區參與,同時也具有大公司的支持,指導和穩定性。

正是因為有著大量的優勢,TensorFlow適合個人和企業,從初創公司到大型公司,以及Google。即從2015年11月開源以來,TensorFlow已經成為最為令人興奮的機器學習庫之一。它被越來越多地應用到研究,生產和教育中。

TensorFlow庫有著持續的改進,增加和優化,社區的發展也非常迅速。

TensorFlow:名字中包含了什麼呢?

張量(Tensor)是在深度學習中最基本的表示數據的方式。簡單的說,張量就是多維數組,有著更高維度的二維表格(矩陣)的拓展。

一個張量,簡單地說,就是一個n為的矩陣

一般來說,如果你對矩陣數學更熟悉,你可以像矩陣一樣考慮張量!

在這篇文章中,我們會討論,並簡單的了解TensorFlow的基礎內容:Variables, Sessions, Placeholders等等。同時,我們會展示如何在你的系統上安裝TensorFlow。

安裝TensorFlow

如果你是剛剛安裝了Python(或者是為了學習TensorFlow的目的安裝的),你可以從下面的pip安裝開始:

但是,這個方法的壞處在於,TensorFlow會覆蓋現有的包,並安裝特定的版本來滿足依賴性。

如果你要使用這個Python來做其他用途的話,這個方法是不可行的。一個常見的做法就是在虛擬環境中安裝TensorFlow,通過一個叫做virtualenv的軟體實現。這取決於你的環境,你可能不需要在你的機器上安裝virtualenv。要安裝virtualenv的話,輸入:

為了在虛擬環境中安裝TensorFlow,你必須要先創建虛擬環境——在這篇文章匯總,我們選在將其放在~/envs目錄中,可以隨意放在你喜歡的任何地方。

這會在~/envs目錄下創建一個名為TensorFlow的虛擬環境(會展現為~/envs/tensorflow目錄的形式)。要啟動這個虛擬環境,使用:

提示會發現變化表明環境已經啟動了。

在這個使用輸入pip的安裝命令:

這樣TensorFlow就會安裝在虛擬環境中了,而不是影響到已經安裝在你電腦中其他軟體包了。最後,要退出虛擬環境的話,輸入:

這樣你就可以回到正常的提示窗口了。

直到最近TensorFlow一直很難與Windows機器一起使用。 但是到了TensorFlow 0.12,Windows上的安裝到來了! 它很簡單:

上面是CPU的版本,或者是

GPU的版本(假設你已經有了CUDA 8)

TensorFlow的「HelloWorld」

現在,我們已經安裝並設置好了TensorFlow的環境。開始寫一個簡單的TensorFlow的程序吧,將「Hello」和「World」結合起來,顯示出欄位——「HelloWorld」。

儘管這看起來非常簡單明了,但是這個例子會介紹很多TensorFlow中的核心元素,以及它不同常規Python程序的地方。

首先,我們跑一個簡單的安裝和版本檢測(如果你是使用virtualenv的安裝方式,確保你在運行TensorFlow的代碼前有激活環境):

上面的代碼會在終端上輸出TensorFlow的版本信息。運行下面的命令來執行腳本:

在終端上會顯示出你的TensorFlow版本:

如果正確的話,輸出應該是你安裝在系統上的TensorFlow版本信息。版本不匹配是導致問題發生最有可能的原因。

我們完成了檢測TensorFlow的版本。接下來實現HelloWorld的例子。下面是完整的代碼:

假設你熟悉Python和imports,這裡的第一行代碼:

就不需要進行解釋了。接下來,我們定義常量(constant)「Hello」和「World!」,然後兩個常量拼接起來:

到這裡,你可能想知道(如果有的話)這與執行此操作的簡單Python代碼有何不同:

關鍵的地方在於變數hw在兩個例子中所包含的東西。我們可以使用print命令來確認下。在純Python的例子中我們得到:

但是,在TensorFlow的例子中,輸出是完全不同的:

這可能不是你期待的!

TensorFlow的代碼並沒有計算h和w的和,而是將求和運算添加到稍後要完成的計算圖中。

接下來,會話(Session)對象作為一個外部TensorFlow計算機制的介面,可以讓我們執行這已經定義好的部分的計算圖。代碼:

這一行實際上計算了hw(按照我們之前定義好的計算h和w的和),下面列印ans顯示預期的「hello World!」內容。

到此完成了第一個TensorFlow的例子。運行下面的命令來執行腳本:

會話(Session)

按照上面的代碼,你應該已經注意到了Session的使用。現在是時候了解下會話是什麼了。

會話對象是TensorFlow API的一部分,它在Python對象和我們的數據之間進行通信,以及為我們定義的對象分配內存的實際計算系統,存儲中間變數,最後返回結果給我們。

會話對象的執行部分是由.run()方法完成的。當調用的時候,這個方法按照下面的方式完成一組計算:首先從請求的輸出開始,然後從後往前自行,根據一系列的依賴計算必須執行的結點。因此,圖的計算部分取決於我們的輸出查詢。

在我們的例子中,我們請求計算結點f,並得到5的數值作為輸出。

當我們的計算任務完成,使用sess.close()命令來結束會話是一個好的習慣,確保所有會話使用的資源都被釋放了。這是要保持的一個非常重要的習慣,儘管我們沒有要求一定要這樣做。

關於構造函數的注釋

tf.函數可以認為是一個構造函數,但更準確地說,實際上根本不是一個構造函數,而是一個工廠方法,有時不僅僅是創建操作符對象。

計算圖的介紹

TensorFlow可以讓我們實現機器學習演算法,通過創建和計算操作來進行交互。這些交互的形式我們稱之為「計算圖」,我們可以在上面直觀地表示出複雜的功能架構。

對於新了解這個概念的人來說,圖形是指一組互連的實體,通常稱為節點或頂點。這些節點通過邊相連。在數據流圖中,邊允許數據定向地從一個節點流動到另外一個節點。

在TensorFlow中,每個圖的節點表示可能應用於某些輸入的操作,並且可以生成傳遞給其他節點的輸出。

圖的操作包含了各式各樣的函數,從簡單的計算,比如減法和乘法到複雜的,等下我們會介紹。還包括更多一般的操作,如創建摘要,生成常量值等。

我們來看看一個簡單的例子:

在上面的例子中,我們看到一個基本加法的圖。由圓圈表示的函數接收兩個輸入,圖中為兩個指向函數的箭頭。輸出1和4相加的結果:5,圖中顯示為函數的輸出指向。這個結果可以傳遞給另外的函數,或者是簡單的返回給客戶。我們也可以看下用一個簡單的方程式來表示這個圖:

以上說明了在構造計算圖時如何使用圖,節點和邊的兩個基本構建塊。讓我們來看看他們的特性:

節點,通常表示成圓形,橢圓形或者方框,代表某種計算或者行為,或者是圖中上下文的數據。在上面的例子中,操作「add」是單獨的結點。

邊是傳遞給操作和從操作傳遞的實際值,通常繪製為箭頭。在「add」 的例子中,輸入1和2都是通向節點的邊,而輸出3是通向節點的邊。 從概念上講,我們可以將邊視為不同操作之間的鏈接,因為它們將信息從一個節點傳遞到下一個節點。

對於這個圖還可以繼續深入挖掘!根據箭頭的指引,數據的傳輸方向是從左往右,現在從左邊開始,把這個圖拆解開來。

起初這兩個值從左側流入圖中,即 9 和 5.

它們來自不同的圖,從文件中讀取或是直接由客戶端輸入

每一個初始值都被傳輸到其中一個顯式節點,在圖中標記為 a 和 b.

「輸入」節點只是起到傳遞值的作用——節點 a 接收值 9 並輸出等值到節點c 和 d, 而節點 b 則對值 5 進行相同的操作。

節點 c 是乘法操作。它接收來自節點 a 和節點 b 的值 9 和 5,並將值 45 輸出到節點 e .同時節點 d 對同等的輸入值進行加法操作並將結果值 14 輸出到節點 e。

最後,圖中的末端節點 e ,是另一個「加法」節點。它接收值 45 和 14 ,並將它們相加,然後輸出結果值 59 作為圖的最終結果。

以下將上述的圖表示成一系列的等式:

如果 a = 5 , b=3 ,想求解 e 的話,只需要將e用 a 和 b 表示出來,並將 a,b 的值代入等式即可

基於此,計算部分完成!下述是值得推敲的概念:

「輸入」節點的工作機制非常有用,它允許用戶將單個輸入值中繼到後面的節點。否則客戶端(或傳入初始值的人)必須將每個輸入值顯式傳遞給圖中的多個節點。 客戶端只需要關心第一次傳入的值,並且重複使用的任何輸入都會被進行抽象,接下來會介紹抽象圖。

小考題:首先執行 c 和 d 中的哪一個?還是說其他的節點?

答案是:無法辨別 。從這張圖中無法知道首先執行 c 和 d 中的哪一個。 有些人會從左到右和從上到下閱讀圖表,並簡單地假設節點c將首先運行,但重要的是,要注意圖表可以很容易地在節點 c 的基礎上繪製 d 。 其他人可能會認為這些節點同時運行,但由於各種限制原因,情況並非總是如此。實際上,較好的方式是將它們視為彼此獨立運行,因為節點c不依賴於來自節點d的任何信息,所以它不必等待節點 d 以完成其操作;反之也同樣成立:節點 d 不需要來自節點c的任何信息。

構建你的一個TensorFlow圖

上面的部分已經讓我們對下面的圖有了一定的了解,這裡是關於TensorFlow的代碼:

現在我們一行一行地來看。首先,你會注意到導入的聲明:

這句代碼沒有令人疑惑的地方,導入TensorFlow庫並命名為tf。這是按照慣例,因為當我們使用它的各種功能時,更容易輸入「tf」而不是一遍又一遍拼寫比較長的「tensorflow」!

接下來,我們關注下兩個變數的賦值:

在這裡,我們定義「輸入」節點,a和b。這兩行代碼使用了我們的第一個TensorFlow操作:tf.constant()。在TensorFlow中,任何在圖中的計算節點稱作一個操作(Operation)或者簡寫為Op。傳入一個單一的Tensor值,輸出同樣的值給直接相連的結點。

為了方便,這個函數幫我們自動將數值常量5和9轉換成Tensor對象。我們還傳入一個可選的字元串名稱參數,可以使用該參數為我們創建的節點提供標識符。

這裡,我們定義的圖的下兩個節點,都使用到了之前定義的節點。節點c使用tf.mul Op,接收兩個輸入,輸出是這兩個輸入的乘積結果。

同樣的,節點d使用tf.add,一個輸出為兩個輸入和的操作。我們再次為這兩個Ops傳遞一個名稱(這是你會經常看到的)。

注意,我們並不需要自己分別定義圖中節點的邊,當你在TensorFlow創建一個節點時,你包含了操作計算所有需要的節點了,軟體會幫你畫這些連接。

最後一行定義圖的最後一個節點。e使用tf.add,和節點d是類似的。但是這時它的輸入是節點c和d,正是像上面描述的圖一樣。有了這個,我們的第一個,雖然很小的圖已經完全定義好了!如果你想要在Python腳本或者shell中執行上面的代碼,它完全可以運行了,但實際上它不會做任何事情。

記住——這只是定義的過程。為了簡要了解運行圖的內容,我們可以在最後添加以下兩行以使我們的圖輸出最終的節點:

如何你在互動式的環境中運行,比如Python Shell或者Jupyter/iPython Notebook,你會看到正確的輸出:

數據類型

張量有一個數據類型。通過圖形的基本數據單位是數值、布爾值或字元串元素。當我們從上一個代碼示例中列印出張量對象c時,我們看到它的數據類型是一個浮點數。因為我們沒有指定數據的類型,所以TensorFlow自動默認為它。

例如,9被視為整數,而像9.1這樣有小數點的任何數都被視為浮點數。

我們可以通過在創建張量對象時指定要處理的數據類型來顯式地選擇數據類型。通過屬性dtype,我們可以看到給定的張量對象被設置了什麼類型的數據:

常量

在TensorFlow中,使用函數constant來創建常量,常量的聲明是constant(value, dtype=None, shape=None, name="Const", verify_shape=False),value是一個恆定值將用於進一步計算,dtype是數據類型參數(例如,float32/64, int8/16等等。),shape是可選的尺寸形狀,name是一個可選的張量名字,最後一個參數是一個布爾值,表示驗證值的形狀。

如果你需要在你的訓練模型中包含特定值的常量,那麼常量對象可以如下例所示:

張量的形狀

張量的形狀是每個維中的元素個數。在圖形構造過程中,TensorFlow自動推斷形狀。張量的形狀,既描述了張量中的維數,也描述了每個維的長度。

張量形狀可以是Python列表,也可以是包含有序整數集的元組:列表中的數字和維度一樣多,每個數字都描述了對應維度的長度。例如,列表[3,4]描述了長度為3的三維張量在第一個維度的形狀,長度為4的三維張量在第二個維度的形狀。注意,可以使用元組(())或列表([])定義形狀。

讓我們來看看更多的例子來進一步說明這一點:

我們可以通過傳遞None作為維度的值來分配一個靈活的長度。將None作為形狀傳遞將告訴TensorFlow允許任何形狀的張量。也就是說,一個任意維數任意長度的張量:

tf.shape 操作可以用來找到一個張量的形狀,如果需要的話。它只需要接收你想要找到形狀的張量對象,就能以int32向量的形式返回:

張量只是矩陣的超級集合!

tf.shape與任何其他操作一樣,shape直到在會話中執行時才會運行。

命名

張量對象可以用命名來標識,它是內部字元串。

與 dtype 同理,可以使用 .name 屬性來查看對象的命名:

Tensor對象的命名是其對應操作的名稱(「c」;與冒號連接),後面是生成它的操作輸出中的張量索引 - 可能有多個。

命名範圍

在TensorFlow中,可以將大型的複雜圖組合在一起,以便易於管理。

節點可以按名稱分組,通過使用 tf.name_scope(「前綴」)Op和 with 語句來完成。

在示例中,將變數 c2 和 c3 中包含的對象範圍 prefix_name 下進行分組,該變數在其名稱中為前綴。

前綴用於將圖形劃分為具有某種語義含義的子圖。

Feed 字典

Feed用於臨時替換張量值操作的輸出,參數 feed_dict 用於覆蓋圖中的Tensor 值,並且將 Python 字典對象作為輸入,字典中的鍵是會被覆蓋的 Tensor 對象的句柄,而值可以是數字、字元串、列表或NumPy數組(如前所述),feed_dict 可用於指定輸入值。

小貼士:值必須與Tensor 鍵具有相同的類型(或能夠轉換為相同的類型)

下圖所示是使用 feed_dic 去重寫之前圖中的 a 值:

變數

Tensorflow 中的特定對象叫做變數。與每次運行 Session 時「重新填充」數據的其他 Tensor 對象不同,它們可以在圖中保持固定的狀態。

與其他的 Tensor 對象類似,變數也可以作為圖中其他操作的輸入

變數的使用可通過兩步搞定:

調用 tf.Variable() 函數,以創建一個變數並定義其初始值

通過在 session 會話中執行 tf.global_variables_initializer() 方法進行初始化,這會為變數分配內存並設定初始值

與其他的 Tensor 對象同理,變數可在運行模塊時進行計算,如下所示:

值得注意的是,如果再次執行該代碼,可看到每次都會生成新的變數,表示形式為變數名稱_1 :

小貼士:為了重複使用相同的變數,可使用 tf.get_variables() 函數,而不是 tf.Variable().

佔位符

佔位符是由 TensorFlow 指定的用於輸入值的結構。 也可以認為它們是空變數,稍後將填充數據。它們首先用於構造我們的圖形,並且只有在執行時才會使用輸入數據。佔位符可選 shape 參數。

如果 shape 參數被輸入或作為 None 傳遞,那麼可以用任何大小的數據替換佔位符:

每當定義一個佔位符,都必須用傳入輸入值,否則將拋出異常。

首先導入tensorflow, 然後創建一個名為 x 的佔位符,即內存中稍後存儲值的位置。

然後創建一個Tensor,它是將x乘以2的運算。

注意,還沒有為 x 定義初始值。

現在定義了操作(y),可在會話中運行。創建一個會話對象,然後只運行 y 變數。

請注意,這意味著如果定義了更大的操作圖,也只能運行圖的一小部分。

這個子圖評估實際上是 TensorFlow 的一個賣點,非常標新立異。運行 y 需要獲取 x 的值,可在 feed_dict 參數中定義以運行。

在這裡聲明 x 的值是[1,2,3],在運行 y 後,得到結果為 [2,4,6] 。

結論

TensorFlow是一個功能強大的框架,可以輕鬆地處理數學表達式和多維數組 - 這在機器學習中是必不可少的。

之前已經介紹了TensorFlow的基礎知識,之後將開始進入 TensorFlow 的深化階段。

在隨後的教程中,將了解如何利用 TensorFlow 庫來解決優化問題並制定預測分析方程式。

還將使用線性回歸方程和 Logistic 回歸訓練模型來解決XOR問題。

感謝閱讀,請隨時發表評論!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 AI研習社 的精彩文章:

利用事件相機將模糊視頻還原成高速清晰視頻

TAG:AI研習社 |