以Go綁定實例理解TensorFlow
本文通過一個簡單的Go綁定實例,讓讀者一步一步地學習到Tensorflow有關(guān)ID、作用域、類型等方面的知識。以下是譯文。
Tensorflow并不是機器學習方面專用的庫,而是一個使用圖來表示計算的通用計算庫。它的核心是用C++實現(xiàn)的,并且還有不同語言的綁定。Go語言綁定是一個非常有用的工具,它與Python綁定不同,用戶不僅可以通過Go語言使用Tensorflow,還可以了解Tensorflow的底層實現(xiàn)。
綁定
Tensorflow的開發(fā)者正式發(fā)布了:
C++源代碼:真正的Tensorflow核心,實現(xiàn)了具體的高級和低級操作。
Python綁定和Python庫:這個綁定是由C++實現(xiàn)自動生成的,這樣我們可以使用Python來調(diào)用C++函數(shù)。此外,這個庫將調(diào)用融合到了綁定中,以便定義更高級別的API。
Java綁定。
Go綁定。
作為一個Go開發(fā)者而不是一個Java愛好者,我開始關(guān)注Go綁定,以便了解他們創(chuàng)建了什么樣的任務(wù)。
Go綁定
地鼠與Tensorflow的徽標
首先要注意的是,Go API缺少對Variable的支持:該API旨在使用已經(jīng)訓練過的模型,而不是從頭開始訓練模型。安裝Tensorflow for Go的時候已經(jīng)明確說明了:
TensorFlow提供了可用于Go程序的API。這些API特別適合于加載用Python創(chuàng)建并需要在Go程序中執(zhí)行的模型。
如果我們對培訓ML模型不感興趣,萬歲!相反,如果你對培訓模型感興趣,那就有一個建議:
作為一個真正的Go開發(fā)者,保持簡單!使用Python定義并訓練模型;你可以隨時使用Go來加載并使用訓練過的模型!
簡而言之,go綁定可用于導入和定義常量圖;在這種情況下,常量指的是沒有經(jīng)過訓練的過程,因此沒有可訓練的變量。
現(xiàn)在,開始用Go來深入學習Tensorflow吧:讓我們來創(chuàng)建第一個應(yīng)用程序。
在下文中,我假設(shè)讀者已經(jīng)準備好Go環(huán)境,并按照README(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/go/README.md)中的說明編譯并安裝了Tensorflow綁定。
理解Tensorflow結(jié)構(gòu)
讓我們來重復一下什么是Tensorflow:
TensorFlow?是一款使用數(shù)據(jù)流圖進行數(shù)值計算的開源軟件庫。圖中的節(jié)點表示數(shù)學運算,而圖的邊表示在節(jié)點之間傳遞的多維數(shù)據(jù)數(shù)組(張量)。
我們可以把Tensorflow視為一種描述性語言,這有點像SQL,你可以在其中描述你想要的內(nèi)容,并讓底層引擎(數(shù)據(jù)庫)解析你的查詢、檢查句法和語義錯誤、將其轉(zhuǎn)換為內(nèi)部表示形式、進行優(yōu)化并計算出結(jié)果:所有這一切都會給你正確的結(jié)果。
因此,當我們使用任何一個API時,我們真正做的是描述一個圖:當我們把圖放到Session中并顯式地在Session中運行圖時,圖的計算就開始了。
知道了這一點之后,讓我們試著來定義一個計算圖并在一個Session中進行計算吧。API文檔(https://godoc.org/github.com/tensorflow/tensorflow/tensorflow/go)為我們提供了(簡寫為)和包中所有方法的列表。
我們可以看到,這兩個包包含了我們需要定義和計算圖形的所有內(nèi)容。
前者包含了構(gòu)建一個基本的“空”結(jié)構(gòu)(就像Graph本身)的功能,后者是包含由C++實現(xiàn)自動生成綁定的最重要的包。
然而,假設(shè)我們要計算A與x的矩陣乘法,其中
我假設(shè)讀者已經(jīng)熟悉了tensorflow圖定義的基本思想,并且知道占位符是什么以及它們?nèi)绾喂ぷ?。下面的代碼是對Tensorflow Python綁定的第一次嘗試。我們來調(diào)用這個文件attempt1.go
代碼注釋的很詳細,希望讀者能閱讀每一行注釋。
現(xiàn)在,Tensorflow-Python用戶期望該代碼進行編譯并正常工作。我們來看看它是否正確:
這是他看到的結(jié)果:
等等,這里發(fā)生了什么? 顯然,存在兩個名稱都為“Placeholder”的操作。
第一節(jié)課:節(jié)點ID
每當我們調(diào)用一個方法來定義一個操作時,Python API都會生成不同的節(jié)點,無論是否已經(jīng)被調(diào)用過。下面的代碼返回3。
我們可以通過打印占位符的名稱來驗證此程序是否創(chuàng)建了兩個不同的節(jié)點:print(a.name,b.name)生成Placeholder:0 Placeholder_1:0,因此,b占位符是Placeholder_1:0,而a占位符是Placeholder:0。
在Go中,相反,之前的程序會執(zhí)行失敗,因為A和x都命名為Placeholder。我們可以得出這樣的結(jié)論:
Go API不會在每次調(diào)用函數(shù)來定義操作的時候自動生成新的名字:操作的名字是固定的,我們無法修改。
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%