天天看點

《面向機器智能的TensorFlow實踐》引言

本節書摘來自華章出版社《面向機器智能的tensorflow實踐》一書中的第1章,第節,作者山姆·亞伯拉罕(sam abrahams)丹尼亞爾·哈夫納(danijar hafner)[美] 埃裡克·厄威特(erik erwitt) 阿裡爾·斯卡爾皮内裡(ariel scarpinelli),更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

引  言2

1.1 無處不在的資料

我們正實實在在地處于“資訊時代”。如今,各種資料從無窮無盡的管道不斷湧入:智能手機、手表、汽車、停車計時表、家用電器。幾乎任何一種能夠說出名字的技術與生俱來都具備與位于雲端的某個資料庫進行通信的能力。在看似無限的存儲能力的支援下,開發者們為資料倉庫選擇了一種“更多即是更好”的方法,存儲着從他們的産品和客戶那裡收集到的以拍位元組(pb)為機關計的海量資料。

與此同時,計算機的性能也在持續提升。雖然cpu的發展速度已經放緩,但并行處理架構取得了爆炸式的發展。一向主要服務于計算機遊戲的圖形處理單元(gpu)如今已被大量運用于通用計算領域,并拉開了機器學習迅猛發展的序幕。

機器學習(有時簡記為ml)試圖利用通用的數學模型回答涉及資料的特定問題。機器學習成功應用于垃圾郵件檢測、産品推薦(向客戶)、預測商品的價格等領域已有多年。近年來,一種特殊類型的機器學習範式在幾乎所有領域都取得了無數巨大的成功,它就是深度學習。

1.2 深度學習

“深度學習”已成為用于描述使用多層神經網絡的過程的标準術語,多層神經網絡是一類極為靈活的可利用種類繁多的數學方法以及不同數學方法組合的模型。這類模型極為強大,但直到最近幾年,人們才有能力卓有成效地利用神經網絡,其背後原因主要有兩點,一是擷取足夠數量的資料成為現實;二是得益于通用gpu的快速發展,多層神經網絡擁有了超越其他機器學習方法所必需的計算能力。

深度學習的強大之處在于當決定如何最有效地利用資料時,它能夠賦予模型更大的靈活性。人們無需盲目猜測應當選擇何種輸入。一個調校好的深度學習模型可以接收所有的參數,并自動确定輸入值的有用高階組合。這種能力使得更為複雜的決策過程成為可能,并使計算機比以往任何時候都更加智能。借助深度學習,我們可以制造出具有自動駕駛能力的汽車和能夠了解人類語音的電話。由于深度學習的出現,機器翻譯、人臉識别、預測分析、機器作曲以及無數的人工智能任務都成為可能,或相比以往有了顯著改進。

雖然深度學習背後的數學概念幾十年前便提出,但緻力于建立和訓練這些深度模型的程式設計庫是近年來才出現的。遺憾的是,這些庫中的大多數都會在靈活性和生産價值之間進行取舍。靈活的庫對于研究新的模型架構極有價值,但常常或者運作效率太低,或者無法運用于産品中。另一方面,雖然出現了可托管在分布式硬體上的快速、高效的庫,但它們往往專注于特定類型的神經網絡,并不适宜研究新的和更好的模型。這就使決策制定者陷于兩難境地:是應當用缺乏靈活性的庫來從事研究,以避免重新實作代碼,還是應當在研究階段和産品開發階段分别使用兩個完全不同的庫?如果選擇前一種方案,可能便無法測試不同類型的神經網絡模型;如果選擇後一種方案,則需要維護可能調用了完全不同的兩套api的代碼。由此甚至會引發另一個問題—我們是否擁有這樣的資源?

解決這個兩難問題正是tensorflow的設計初衷。

1.3 tensorflow:一個現代的機器學習庫

tensorflow由谷歌于2015年11月向公衆正式開源,它是汲取了其前身—distbelief在建立和使用中多年積累的經驗與教訓的産物。tensorflow的設計目标是保證靈活性、高效性、良好的可擴充性以及可移植性。任何形式和尺寸的計算機,從智能手機到大型計算叢集,都可運作tensorflow。tensorflow中包含了可即刻将訓練好的模型産品化的輕量級軟體,有效地消除了重新實作模型的需求。tensorflow擁抱創新,鼓勵開源的社群參與,但也擁有一家大公司的支援、引導,并保持一定的穩定性。由于其強大的功能,tensorflow不僅适合個人使用,對于各種規模的公司(無論是初創公司,還是谷歌這樣的大公司)也都非常适合。

如果你和你的同僚擁有資料、一個有待求解的問題以及一台可工作的計算機,那麼很幸運,tensorflow正是你們一直尋找的“武林秘籍”。

1.4 tensorflow:技術概要

本小節将給出一些關于tensorflow庫的高層資訊,如它是什麼、它的發展史、用例以及與競争對手的比較。決策制定者、利益相關者以及任何希望了解tensorflow背景的人都會從本小節受益。

谷歌的深度學習研究簡史

谷歌最初開發的大規模深度學習工具是谷歌大腦(google brain)團隊研發的distbelief。自建立以來,它便被數十個團隊應用于包括深度神經網絡在内的不計其數的項目中。然而,像許多開創性的工程項目一樣,distbelief也存在一些限制了其易用性和靈活性的設計錯誤。distbelief完成之後的某個時間,谷歌發起了新的項目,開始研發新一代深度學習工具,其設計準備借鑒最初的distbelief在使用中總結的教訓和局限性。這個項目後來發展為tensorflow,并于2015年11月正式向公衆開源,接着迅速成為一個頗受歡迎的機器學習庫,如今已被成功運用于自然語言處理、人工智能、計算機視覺和預測分析等領域。

1.5 何為tensorflow

下面以一種高層觀點來介紹tensorflow,以幫助讀者了解它試圖求解的問題。

1.5.1 解讀來自官網的單句描述

在tensorflow的官網上,針對通路者的第一句緻辭便是下列(相當含糊的)聲明:

tensorflow is an open source software library for machine intelligence

這句話的下方,即“about tensorflow”下的一段還有這樣一句描述:

tensorflowtm is an open source software library for numerical computation

using data flow graphs.

比起前面的聲明,第二個定義更為具體,但對那些數學或技術背景不強的人而言,這可能并非最全面的解釋。下面我們對其進行解構。

1. open source(開源)

tensorflow最初是作為谷歌的内部機器學習工具而建立的,但在2015年11月,它的一個實作被開源,所采用的開源協定是apache 2.0。作為開源軟體,任何人都可自由下載下傳、修改和使用其代碼。開源工程師可對代碼添加功能和進行改進,并提議在未來版本中打算實施的修改。由于tensorflow深受廣大開發者歡迎,是以這個庫每天都會得到來自谷歌和第三方開發者的改進。

注意,嚴格來說,我們隻能稱之為“一個實作”,而不能說“tensorflow” 被開源。從技術角度講,tensorflow是《tensorflow白皮書》所描述的一個用于數值計算的内部接口,其内部實作仍然由谷歌維護。然而,開源實作與谷歌的内部實作之間的差異是由與其他内部軟體的連接配接造成的,并非谷歌有意“将好東西藏着掖着”。谷歌始終都在不斷将内部改進推送到公共代碼庫。總之,tensorflow的開源版本包含了與谷歌的内部版本完全相同的功能。

在本書後續内容中,當提到“tensorflow”時,筆者實際上指的是其開源實作。

2. library for numerical computation(數值計算庫)

官網的定義中并未将tensorflow稱為一個“機器學習庫”,而是使用了更寬泛的短語“數值計算”。雖然tensorflow中的确包含一個模仿了具有單行模組化功能的機器學習庫scikit-learn的名為“learn”(也稱“scikit flow”)的包,但需要注意的是,tensorflow的主要目标并非是提供現成的機器學習解決方案。相反,tensorflow提供了一個可使使用者用數學方法從零開始定義模型的函數和類的廣泛套件。這使得具有一定技術背景的使用者可迅速而直覺地建立自定義的、具有較高靈活性的模型。此外,雖然tensorflow為面向機器學習的功能提供了廣泛支援,但它也非常适合做複雜的數學計算。然而,由于本書重點讨論機器學習(尤其是深度學習),是以下面主要講述如何利用tensorflow建立“機器學習模型”。

3. data flow graphs(資料流圖)

tensorflow的計算模型是有向圖(directed graph),其中每個節點(通常以圓圈或方框表示)代表了一些函數或計算,而邊(通常以箭頭或線段表示)代表了數值、矩陣或張量。

資料流圖極為有用的原因如下。首先,許多常見的機器學習模型,如神經網絡,本身就是以有向圖的形式表示的,采用資料流圖無疑将使機器學習實踐者的實作更為自然。其次,通過将計算分解為一些小的、容易微分的環節,tensorflow能夠自動計算任意節點關于其他對第一個節點的輸出産生影響的任意節點的導數(在tensorflow中稱為“operation”)。計算任何節點(尤其是輸出節點)的導數或梯度的能力對于搭建機器學習模型至關重要。最後,通過計算的分解,将計算分布在多個cpu、gpu以及其他計算裝置上更加容易,即隻需将完整的、較大的資料流圖分解為一些較小的計算圖,并讓每台計算裝置負責一個獨立的計算子圖(此外,還需一定的邏輯對不同裝置間的共享資訊進行排程)。

補充:何為張量?

簡而言之,張量是一個n維矩陣。是以,2階張量等價于标準矩陣。從可視化的角度,若将m×m的矩陣視為方形數組(m個數字高,m個數字寬),則可将m×m×m的張量視為立方數組(m個數字高,m個數字寬,m個數字深)。一般而言,如果讀者更熟悉矩陣數學,完全可以按矩陣的方式來看待張量。

1.5.2 單句描述未展現的内容

雖然短語“open source software library for numerical computation using data

flow graphs”的資訊密度非常大,但并未涵蓋那些真正使tensorflow作為機器學習庫脫穎而出的重要方面。下面列出一些成就tensorflow的重要組成。

1.分布式功能

上文在介紹資料流圖時間接提到,tensorflow的設計目标之一是在多台計算機以及單機多cpu、單機多gpu環境中具有良好的可伸縮性。雖然,最初的開源實作在釋出時并不具備分布式功能,但自0.8.0版本起,分布式運作時已成為tensorflow内置庫的一部分。雖然這個最初版本的分布式api有些臃腫,但它極其強大。大多數其他機器學習庫尚不具備這樣的功能,尤其值得注意的是,tensorflow與特定叢集管理器(如kubernetes)的本地相容性正在得到改善。

2.軟體套件

雖然“tensorflow”主要是指用于建構和訓練機器學習模型的api,但tensorflow實際上是一組需配合使用的軟體:

tensorflow是用于定義機器學習模型、用資料訓練模型,并将模型導出供後續使用的api。雖然實際的計算是用c++編寫的,但主要的api均可通過python通路。這使得資料科學家和工程師可利用python中對使用者更為友好的環境,而将實際計算交給高效的、經過編譯的c++代碼。tensorflow雖然也提供了一套可執行tensorflow模型的c++ api,但在本書編寫之時它還具有較大的局限性,是以對大多數使用者都是不推薦的。

tensorboard是一個包含在任意标準tensorflow安裝中的圖可視化軟體。當使用者在tensorflow中引入某些tensorboard的特定運算時,tensorboard可讀取由tensorflow計算圖導出的檔案,并對分析模型的行為提供有價值的參考。它對概括統計量、分析訓練過程以及調試tensorflow代碼都極有幫助。學會盡早并盡可能多地使用tensorboard會為使用tensorflow工作增添趣味性,并帶來更高的生産效率。

tensorflow serving是一個可為部署預訓練的tensorflow模型帶來便利的軟體。利用内置的tensorflow函數,使用者可将自己的模型導出到可由tensorflow

serving在本地讀取的檔案中。之後,它會啟動一個簡單的高性能伺服器。該伺服器可接收輸入資料,并将之送入預訓練的模型,然後将模型的輸出結果傳回。此外,tensorflow serving還可以在舊模型和新模型之間無縫切換,而不會給最終使用者帶來任何停機時間。雖然serving可能是tensorflow生态系統中認可度最低的組成,它卻可能是使tensorflow有别于其他競争者的重要因素。将serving納入生産環境可避免使用者重新實作自己的模型—他們隻需使用tensorflow導出的檔案。tensorflow serving完全是用c++編寫的,其api也隻能通過c++通路。

筆者相信,隻有深入了解上述所有軟體之間的聯系,并熟練掌握它們的聯合使用方法,方可真正使tensorflow物盡其用。是以,本書會涵蓋上述三個軟體的用法。

1.6 何時使用tensorflow

下面介紹一些tensorflow的用例。一般而言,對于大多數機器學習任務,tensorflow都是一個很好的選擇。下面簡單列出了tensorflow尤其适合的一些場合。

研究、開發和疊代新的機器學習架構。由于tensorflow極為靈活,是以在建構新穎的、測試較少的模型時非常有用。而使用某些庫時,使用者隻能擷取對實作原型有幫助的具有較強剛性的預模組化型,而無法對其進行修改。

将模型從訓練直接切換到部署。如前所述,tensorflow serving使使用者可實作訓練到部署的快速切換。是以,在建立依賴于機器學習模型的産品時,使用tensorflow便可實作快速疊代。如果你的團隊需要保持較快的開發進度,或者你隻是沒有用c++、java等語言重新實作某個模型的資源,tensorflow可賦予你的團隊快速實作産品的能力。

實作已有的複雜架構。一旦使用者掌握了如何閱讀可視化的計算圖,并使用tensorflow來進行建構,他們便有能力用tensorflow實作最新的研究文獻中所描述的模型。在建構未來的模型,或甚至在對使用者的目前模型進行嚴謹的改進時,這種能力可提供非常有價值的見解。

大規模分布式模型。在面對多種裝置時,tensorflow表現出卓越的向上可擴充性。它已經開始在谷歌内部的各個項目中逐漸取代distbelief。随着最近分布式運作時的釋出,我們将看到越來越多的将tensorflow運作于多台硬體伺服器和雲端虛拟機的用例。

為移動/嵌入式系統建立和訓練模型。雖然tensorflow主要關注向上的擴充(scaling up),對于向下的擴充(scaling down),它同樣有優異的表現。tensorflow的靈活性之一展現在它可輕松擴充到計算性能不高的系統中。例如,它可在安卓裝置以及像樹莓派(raspberry pi)這樣的微型計算機中運作。tensorflow代碼庫中包含了一個在安卓系統中運作預訓練模型的例程。

1.7 tensorflow的優勢

1.易用性

相對而言,tensorflow工作流易于了解。它的api保持着高度的一緻性,這意味着在嘗試不同模型時,無需從頭學習一套新的東西。

tensorflow api很穩定,維護者始終在努力確定每次改動都向下相容。

tensorflow與numpy無縫內建,可使大多數了解python的資料科學家如魚得水。

不同于其他庫,tensorflow不占編譯時間。這就使使用者可快速驗證自己的想法,而省去了專門的等待時間。

目前已有多種高層接口建構在tensorflow之上,如keras和skflow。這就使得即便使用者不希望動手實作整個模型,也可以利用tensorflow的優勢。

2.靈活性

tensorflow能夠運作在不同類型和尺寸的機器之上。這使得tensorflow無論是在超級計算機上,還是在嵌入式系統,或任何其他介于兩者之間的計算機上都有用武之地。

tensorflow的分布式架構使得在大規模資料集上的模型訓練可在合理的時間内完成。

tensorflow可利用cpu、gpu,或同時使用這兩者。

3.高效性

當tensorflow的第一個版本釋出時,它在很多流行的機器學習基準測試中都非常低效。從那時起,tensorflow的開發團隊便投入大量的時間和精力對tensorflow代碼的大部分實作進行改進。如今,tensorflow中大部分庫的性能已有了顯著提升,已成為衆多開源機器學習架構中居于榜首位置的有力競争者。

tensorflow的效率仍在持續地得到改進,因為有越來越多的開發者正在共同努力帶來更好的實作。

4.幕後支援

tensorflow為谷歌所支援。谷歌已為其投入巨大的資源,因為它希望tensorflow成為機器學習研究者和開發者的通用語言。此外,谷歌也在利用tensorflow完成其日常工作,并且通過投資來為tensorflow提供持續不斷的支援。

圍繞tensorflow已經形成了一個不可思議的社群,從社群中的知名成員或github上的知名開發者那裡得到回應相對比較容易。

谷歌已經釋出了若幹用tensorflow預訓練的機器學習模型。它們可供免費使用,使得無需大量資料的流水線便可迅速實作原型系統。

5.額外特性

當需要對模型進行調試和可視化時,tensorboard便展現出極為重要的價值,而在其他機器學習庫中,并無類似的功能。

tensorflow serving可能是會使得更多的初創公司将服務和資源投入到機器學習領域的軟體,因為重新實作代碼來部署某個模型所需付出的代價絕對不可小觑。

1.8 使用tensorflow所面臨的挑戰

1.分布式支援尚不成熟

雖然分布式運作時已正式釋出,但在tensorflow中使用這種特性卻并非想象中那樣容易。在本書寫作之時,為使用該特性,需手工定義每台裝置的角色,這種工作既乏味又容易出錯。由于它是一種全新的特性,是以可供學習的例程較少,想必未來的版本應當會有所改進。如前文所述,對kubernetes的支援已進入開發流水線,但到目前為止,它仍然尚未完成。

2.實作定制代碼的技巧性較強

雖然關于如何用tensorflow建立使用者自己的運算有一份官方指南可供參考,但要将定制的代碼實作到tensorflow中仍然頗費周折。然而,如果希望對主代碼庫做出貢獻,谷歌開發團隊會快速回答你的問題,并檢視你所送出的代碼,以便為吸納你的工作成果進行準備。

3.某些特性仍然缺失

如果你是一名經驗豐富的機器學習專家,并對其他架構具備深入的了解,你可能會發現一些自己喜歡的雖小但十分有用的特性尚未在tensorflow中實作。通常,你想要的這種特性在tensorflow中會有一些替代方案,但這可能無法阻止你的抱怨“為什麼它還未得到本地支援?”

1.9 高歌猛進

無需多言,筆者對tensorflow的未來充滿期待,而且筆者對幫助你開始使用這樣一款強大工具感到激動萬分。下一章将介紹如何安裝tensorflow,并對tensorflow的核心庫、基本使用模式以及環境進行全面講解。

繼續閱讀