1. 程式人生 > >谷歌大神帶你十分鐘看懂TensorFlow

谷歌大神帶你十分鐘看懂TensorFlow

文/資料俠Gasparovic

TensorFlow 是世界上最受歡迎的開源機器學習框架,它具有快速、靈活並適合產品級大規模應用等特點,讓每個開發者和研究者都能方便地使用人工智慧來解決多樣化的挑戰。

今天DT君給大家推薦的這個視訊(及文字實錄),是2017年穀歌開發者大會歐洲站上,谷歌研究院工程師Andrew Gasparovic所做演講。他用深入淺出、妙趣橫生的方式,給大家分享了TensorFlow的發展情況與最新成果。

本文轉自公眾號CDA資料分析師(IDcdacdacda)

大家好,我叫Andrew Gasparovic。我是來自谷歌歐洲研究部蘇黎世的一名工程師,致力於研究機器智慧的基礎設施。

今天我很高興可以給大家介紹如何使用TensorFlow進行機器學習。

首先我將向你們講解TensorFlow,然後再給大家舉一些例子,關於我們如何在Google使用TensorFlow。接著分享一些最新以及即將出現的發展情況。然後再談談如何使用機器學習解決實際問題。

TensorFlow是什麼?

首先介紹下TensorFlow究竟是做什麼的,以及人們為什麼想要使用它。

TensorFlow能夠讓你直接解決各種機器學習任務。目標就是在一般情況下,無論你遇到什麼問題,TensorFlow都可以在一定程度上提供API的支援。

總的來說TensorFlow就是為了快而設計的,所以它針對你實際使用的硬體和平臺做了優化。

其中在機器學習框架方面,TensorFlow的真正獨特之處在於,能夠在5行或者10行程式碼中構建模型。然後應用這個模型,進行擴充套件做出產品。

因此,你能夠在幾十甚至幾百個機器的簇上進行訓練。從而用該模型進行非常低的延遲預測。

我們在這裡稍微展開說一下什麼是模型。以及機器學習是怎樣與模型相關聯的。

這裡有個簡單的預測問題,判斷一張圖片中包含的是貓還是狗。這用傳統的程式設計方法很難甚至不可能解決。因為很難制定出一系列規則,來決定什麼是貓什麼是狗。最重要該如何把握所有的變數,比如品種、姿勢、亮度、以及比例等等。

因此作為替代,我們可以構建一個神經網路。這像是人腦中神經元執行的極簡版本。

圖中每個小點都是一個神經元,這些神經元以層為集合單位被關聯起來。從那些我們所看到的圖片,到我們所能理解的輸出。

接著瀏覽大量貓狗的圖片,它們均被標註為正確的類別,然後進行預測。一開始,所有這些神經元都被隨機地初始化,完全憑猜。

我們要計算猜測與正確結果之間的距離,即誤差。然後使用誤差,來調整神經元之間的連線強度。基本上,我們想緩慢地逼近正確答案。在我們重複上述步驟約一百萬次之後,你就可以得到一個不錯的貓狗預測模型。

但是你真正想實現的,其實是建立一個預測貓狗的網站。使用者給了你一張圖片,你需要告訴他們這當中包含了貓還是狗。在訓練中習得的連線強度,能使你的模型推廣。

因此如果給出一張圖片,即使它從未見過這張圖,並且圖片也沒有附上任何標籤,模型也能預測出圖片中是狗。這是根據從神經元的權值習得的,關於貓狗本質的對比。至少是根據它所看的圖片。

而模型真正能學習到什麼程度,是一個基於模型大小和複雜度的函式。直到最近我們才有相應的計算機效能和工具,可以用來實驗巨大且複雜的模型。

這張圖片是神經網路在5到10年前的樣子,那時還只有為數不多的幾個神經元。每層神經元完全相互連線,但也沒有那麼多層神經元。最後的結果也沒有那麼準確。

事實上對於類似計算機視覺的問題,過去的神經網路幾乎無用武之地。相比於為某個確切的任務,由專家們專門手動調節的模型。

如今可以用來與影象分類的神經網路作比較,這個被稱為Inception。它的設計思路是給出一張圖片,它就能從成千上萬,我記得是大約1萬7千種類別中,預測出圖中包含了什麼。

藉助於TensorFlow的框架,你能夠訓練出這樣的模型。含許多層,並且比早期的神經網路更復雜。

這就是我們說深度學習時所指的"深度”。在這裡'深度'指的就是,層與層之間更深層次的協調。以及隨之產生的更加複雜的連線。最終的結果就是你的模型中,有百萬級別甚至十億級別數量的神經元。這就是為什麼通過深度神經網路得到的結果。能夠極大地優於,早期的手工構建並且手工除錯的模型。

但是,TensorFlow能夠在大型神經網路中表現地如此高效的原因是,它能把你寫的程式碼轉換成操作圖。而真正執行的正是這種圖。

順便提一下,在這些操作之間執行的資料叫做張量(Tensor)。這也是名字的來源。

因為你的模型以圖的形式展現出來,你可以推遲或者刪除不必要的操作。甚至重用部分結果。你還可以很輕鬆地實現的一個過程叫做反向傳播。如果你還記得的話,當我們基於所見的樣本以及計算的誤差,來更新模型中的連線強度。這整個過程就是反向傳播。

因為模型表現為操作圖而不是程式碼,因此你不需要為此寫額外的程式碼。只需直接自動地計算以及應用這些迭代更新。模型表現為圖的另一個好處就是,在你的程式碼中,你可以用一行宣告就表明:"我想這部分圖在這裡執行,我想另一部分圖分散式執行在不同的機器群上"。

你甚至可以說"我想要這部分注重數學的圖在GPU上執行,與此同時,資料輸入部分的程式碼在CPU上執行"。

TensorFlow一開始就可以在CPU和GPU上執行,它還可以在iOS 安卓、甚至Raspberry Pi裝置上載入模型,以及做一些像預測或者分類的推理型任務。

因此在我們的資料中心內部,我們使用專門打造的硬體TPU(tensor processing unit),來提供TensorFlow圖。

所以實現在網路中先反向傳播,然後再前向傳播。每一層神經元之間的連線強度,基本上就是非常大的矩陣數學運算。這正是TPU常做的,並且算得又快又好。

第二版TPU硬體我們稱之為雲TPU,之後我會多談談這方面。

曾有一段時間,Python幾乎是構建TensorFlow圖的唯一選擇。直到現在它也是一個不錯的選擇。Python非常簡單,現成的樣例程式碼非常多,幾乎支援任何內容。

但是也有來自很多其他語言的支援。因為TensorFlow是開源的,長期以來在社群的支援下,越來越多的語言開始支援TensorFlow。所以,最終的情況是,如果你對TensorFlow感興趣,你可以用自己喜歡的語言使用TensorFlow。

在此我想說一下,我的TensorFlow Serving團隊的同事們。上個月剛剛釋出了他們的1.0版本。這對他們來說是一個十分重大的里程碑。

因為TensorFlow Serving是非常高效能的基礎設施。你能夠在自己的伺服器上載入模型,用於低延時的推斷請求。在內部,我們已經把它應用於大約800個產品上 。但是我們想把它作為開源分佈的一部分 。

因為這是在實際部署中很重要的一個方面 。當我們說TensorFlow可用於生產時 ,這才能把用來做研究所寫的程式碼與實際生產用來解決問題相區分 。

還有一個專案是稱為TensorBoard的工具 ,這是包中的視覺化工具之一 。這張圖展示的是針對某個任務模型,學到的手寫體數字簇。

總體來說,把模型的執行過程進行視覺化 ,並且嘗試對模型預測的結果進行除錯 。

一直以來都是一個機器學習的難點,是許多機器學習框架中的薄弱環節。因此正如TensorFlow Serving,這也正是我們想要加入的內容 。

因為你不可能將其投入生產 ,除非真正弄清機器學習模型中的執行原理 。以及明確是否模型預測的結果與預期不同 ,還有當中的原因 。

所以總體而言 ,生產前的準備工作是構建成功框架的關鍵之一 ,這也使它與眾不同 。

TensorFlow自發布以來 ,就成為了GitHub上排名第一的機器學習開源庫 。自從釋出以來的其使用量是驚人的 。這張圖表顯示了它自發行以來,在GitHub上的Star數。上一次我看的時候超過了6萬8千點。

另一個原因就是,我們很重視自己在開源社群中的地位。 對於我們來說,這從來就不是隨意打出一些程式碼,或者隨意從原始碼儲存庫中取出一些 ,選擇開源然後就完事了。

自從釋出以來,開放原始碼和開源貢獻者,一直是整個過程中的重要部分。如今 TensorFlow中有超過1千為外部貢獻者。

其中一些外部貢獻者的添加了很多新的特性,如我前面提到的其他語言,額外的硬體支援。甚至是TensorFlow執行的全新平臺。

我們開源工作的另一個方面是 ,確保使用者能夠高效,並瞭解如何最好地使用TensorFlow。

為此我們已經回答了Stack Overflow上數千個問題,同時也認真地研究並解決了我們GitHub Issue頁面上的問題。我們希望從你在下載框架到實際釋出模型時,都有非常無縫的體驗。

只是需要明確的是,我們經常在谷歌裡中使用TensorFlow。這張圖顯示了隨著時間的推移,我們模型的原始碼控制樹的目錄數量。

橙色線是當我們內部發布TensorFlow,可供所有專案使用時的情況。可以看到在此之前,有一些人對機器學習的興趣 。比如一些人是白色名單,或使用我們先進的框架 。然後在其釋出之後就激增了。

如今,谷歌有6千多個產品使用了TensorFlow。

事實上,幾乎谷歌所有的主要產品都使用TensorFlow,並以某種形式進行機器學習。這給了我們大量的反饋和機會來進行優化。通過簡化API,或新增新的API使其更容易使用。還提供一些我提到過的生產工具。

可以用TensorFlow做什麼?

讓我展示一些TensorFlow的應用例項。因為有各種各樣的問題,這很好的展示它作為框架具有的靈活性。

谷歌翻譯曾經使用逐詞翻譯的模型,一句句的短語,其效能僅此而已。

當中具有上千條由語言學家輸入編寫的手調程式碼。即便如此,這是無法體會人類語言的中差別和差異。

右側是將中文"請問,洗手間在哪裡?"翻譯為"Where Will the restroom?"的例子,有很大的改進空間。我們使用全新的基於深度神經網路的系統,代替了之前的系統系統。該系統稱為神經網路機器翻譯。這是在TensorFlow上執行的。

結果是在一些情況下,許多語言組合的翻譯質量上有顯著提高,達到了85%。

原因在於模型會從整個一系列單詞的角度來考慮,輸入序列和輸出序列。結果是你得到了更自然的輸出,更像人工翻譯的成果。例如 此處"excuse me, where is the toilet?”,就是一個更好的翻譯結果。

繼續這個翻譯的主題。我們在翻譯App中加入實時相機翻譯(Word Lens)。而且是在手機上執行的,能在飛航模式使用,這是非常驚人的。

因為在同樣的模型中,這結合了計算機視覺和翻譯。我們在TensorFlow中加入了特性,使這些成為可能。

如今你可以在一個伺服器的叢集,或一臺機器上對模型進行訓練。你通常會這樣做,然後對取該模型,縮小尺寸。從而適應裝置,同時保持高質量。

谷歌圖片就是加入機器學習功能而大為提升的例子。在6個月時間裡,該團隊使用基於Inception的圖象分類系統,在谷歌圖片中實時使用。

思路就是你通過輸入詞在圖片中進行搜尋。比如輸入"海灘" ,就會得到海灘的圖片。搜尋"雨傘" ,就得到雨傘的圖片。或者甚至搜尋一個抽象的詞如”晴天”。而且之前不用在你的圖片中新增這這些標籤。

另一個使用深層神經網路處理更復雜影象任務的,是來自谷歌研究院的Show and Tell。輸入影象,並輸出文字說明。這也始於Inception模型,但它不只是對出現在影象中的物件進行分類。還會得出自然的描述 並把握影象中物件之間的關係。

為了做到這一點,模型在人工生成說明的例子上進行調整。從而它習得了關係的內容。

當中的副作用是,模型更擅長描述影象中比如顏色的細節。因為它發現在人類更喜歡這類描述。

因此谷歌研究院將整個模型開源。在部落格上有關於這方面很深度的帖子,你可以按照文章連結自己試試。

另外谷歌研究眼在致力於使用計算機視覺,對糖尿病性視網膜病變的狀況進行診斷。

一般來說是你去看眼科醫生,通過拍這樣的影象,分析糖尿病視網膜病變的早期跡象。這很重要,因為如果儘早發現疾病,能夠更容易治療。但發展中國家沒有足夠多的眼科醫生,所以很難及時發現病變。

我們發表在《美國醫學會期刊》上發表了文章,當中指出在診斷該症狀時,計算機視覺能夠達到等同、甚至略優於平均眼科醫生的水平。這讓我們很興奮,因為如果讓該模型得到普及,就能夠幫助發現更多類似症狀,在為時已晚之前。

研究小組的最後一個問題是,讓深層神經網路學習。什麼樣的結構能夠解決不同的問題?那麼我們能做的就是,從表現不佳的機器學習模型開始學習,直到達到一個更準確的模型,而無需人工干預。

這個模型建立了解決問題的機器學習模型,這些問題被稱為學習會學習。這是一個非常令人興奮的領域,未來幾年會在該領域做出很多成果。

在你認為TensorFlow是用於長期研究、或者大預算的大型應用程式時,我想給你看一個種黃瓜的日本農民。

照片後面他的兒子,使用建了黃瓜自動分類器,使用TensorFlow Arduino Controller以及Raspberry Pi。

他通過屬於九個類別的七千根黃瓜樣本訓練模型。這之前每次黃瓜收穫後,他母親需要用10個小時進行這項分類工作。

他說"我想把分類工作交給AI來做,這樣我們可以把更多精力放在培育好的黃瓜上"。在訓練完模型後,他用傳送帶將其與控制器連線,並將許多攝像頭連線到Raspberry Pi。當每條黃瓜沿著傳送帶傳送時,它的影像會被攝像頭捕捉,然後並被自動分類。我認為這是一個實際運用機器學習的出色例子。

TensorFlow的最新進展

我認為自從TensorFlow 1.0版本釋出起,它就非常擅長解決這一系列類問題。從那以後又有很多新的發展。

現在讓我介紹一下。首先它變得更容易使用。就像說過的,在解決給出的各種問題時,TensorFlow非常靈活。

但它使用起來並不是最簡單的。它在底層用分散式執行引擎。這個裝置實際上用於執行影象處理操作,並在處理器中實現對該任務的分配,這個是不變的。

我們在1.0版本後,加入了Layers API。其理念是你可以構建模型,而無需直接進行圖形和操作。但你仍然需要建立網路結構和所有的層,而且這類工作需要手工完成。

然後我們添加了Estimators API,能夠更先進地選模型 結合輸入 並進行訓練和評估。現在的1.3版本,我們添加了另一層,我們稱之為Canned Estimators。只需一行程式碼就能夠建立深層神經網路分類器。

使用Estimators API 你能夠免費獲取,如分散式訓練、自動快照。並且能夠執行混合硬體,比如CPU和GPU。

同時對效能的改進能夠應用於你的模型,我們釋出了用不同硬體組合處理不同的任務的基準。這是很重要的,因為這顯示了隨著時間的推移,我們將如何繼續提高效能。但同樣重要的是, 這說明了針對你的硬體組合,TensorFlow解決問題的效能。

至於不常見的配置,這個之前提到的雲TPU。這是第二代TPU(Tensor Processing Unit)。

第一代我們只用於加快機器學習的推算部分,第二代還加速了訓練部分,總的來說這是一個巨大的進步。因為每個雲TPU能夠每秒能計算180萬億次,但這意味著需要每次連線64個TUP pod。一個pod是每秒能計算11.5萬億次。這是很大的運算量。

之前提到的神經網路翻譯模型,需要一整天進行訓練,而且是用我們能找到的32個GPU。如今達到同樣的正確率,使用1/8的TPU只需半天就可以完成訓練。

在一年內我們將面向外部使用者提供在雲平臺使用雲TPU。之後我會分享這方面的資訊。

還要確保我們能夠充分利用用於處理機器學習任務的任何硬體,無論是TPU還是GPU,甚至只是你的CPU支援的指令等。

我們一直使用編譯器,將之前提到的圖直接轉換為彙編碼,稱為加速線性代數(accelerated linear algebra)。

在TPU上執行時這必不可少,並且在Jet Mode下為CPU和GPU編寫圖。因此能夠選擇你硬體的對應核心。

還有第三適合手機端的模式。你能夠事前編寫模型,然後在移動裝置上執行預測。優點是編寫的模型要小得多,但仍然能夠在特定裝置上高效執行。

關於手機端,最後要注意的是我們推出了TensorFlow Lite。專門為安卓移動裝置推出的全新runtime。原理是在移動應用程式中放入很薄的引擎,完全支援你裝置上的硬體,省去了所有不必要的通用程式碼。

當你結合該編譯模型時,你能夠高效實用硬體,且記憶體佔用小。

因此你能夠進行之前提到的裝置上的推斷任務,或者新出的Federated Learning。當中你可以利用在雲端訓練的模型,與此同時在個人的裝置中有自己的訓練資料。這從未被髮送到雲,但是可以在裝置上整合。

如何開始學習TensorFlow

即使你有很多程式設計經驗,我還是會說進入機器學習領域是很難的,非常難

使用TensorFlow的好處之一在於,你處理的內容最終能夠實際生產出來。不管你是什麼水平,我想提供一些開始起步的建議。

第一個建議是利用網站tensorflow.org。上面有入門部分,附有可以實際操作的介紹,以及一些機器學習的任務。預設需要一些Python的知識,但僅此而已。

一旦開始,你可以一步步跟著教程學習。達到構建卷積網路等內容,這很適合處理影象分類任務。而遞迴神經網路適合處理語言及翻譯任務。

在 playground.TensorFlow.org 上,有很有趣的不同神經網路架構和引數的演示。你可以試著改變層或神經元的數量,改變特徵、學習率等。通過處理簡單分類問題,瞭解神經網路的工作原理。

一旦你準備好開始真正構建用於生產的模型,我建議使用高等級的Estimator,以及Canned Estimator API

因為你會自動地獲得,比如儲存和恢復checkpoint 匯出TensorBoard,以及分散式訓練,不需要額外操作。因此百分之八九十的情況下,Estimators和Canned Estimators是不錯的選擇。

當然通過使用Estimators,只要你願意,你也可以把模型移動到雲TPU,幾乎是自動的。

在g.co/tpusignup 有一個申請表,如果你想了解更多資訊的話。在這些連結中也可以瞭解更多關於TensorFlow Research Cloud的資訊。

面向機器學習研究者,我們免費提供了上千個雲TPU。因為有許多人有好的想法,但缺乏合適硬體進行先進研究。如果你想申請的話,可以看看這些連結。

最後還有一些優秀的機器學習線上課程,比如Google Developers的YouTube頻道。Udacity還有使用TensorFlow的深度學習課程。深入機器學習的理論和數學背景。如果你喜歡那個課程,並且想繼續的話,獲得它的機器學習納米學位是不錯的選擇。

我真的希望你想繼續深入機器學習,因為這是一個令人興奮的領域,這比以往更容易,而且有很多的成果。

注:本文編譯自Andrew Gasparovic在谷歌開發者大會的演講實錄,內容僅為作者觀點,不代表DT財經立場。

譯 | CDA字幕組

題圖 | bilibili

期待更多資料俠乾貨分享、話題討論、福利發放?在公眾號DT資料俠(ID:DTdatahero)後臺回覆“資料社群”,可申請加入DT資料社群。

資料俠門派

本文資料俠Andrew Gasparovic,任職於谷歌歐洲研究院機器智慧部門。飛行員,跑步者,bloopmusic的開發者。