免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
翻譯 Tensorflow之旅

Peter Goldsborough寫的文章,我個人覺得很不錯,就全文翻譯過來,第一次發(fā)表在簡書。原文在此,https://arxiv.org/pdf/1610.01178v1.pdf。

摘要:深度學習是人工智能使用深度神經(jīng)網(wǎng)絡(luò)架構(gòu)的一個分支,它已經(jīng)在計算機視覺,語音識別,自然語言處理等領(lǐng)域取得顯著成果。2015年11月,谷歌開源其內(nèi)部使用多年的用來定義,訓練和發(fā)布機器學習模型的軟件庫,Tensorflow。本文將會把Tensorflow放到現(xiàn)代深度學習理論和軟件實現(xiàn)的框架下評估。我們將討論Tensorflow的基本計算范式和分布式計算模型,它的編程接口還有可視化組件。然后我們再把它和其它深度學習庫,比如Theano,Torch或Caffe做定性和定量對比分析,最后對Tensorflow的已知的學術(shù)界和工業(yè)界使用實例作評估。

一,簡介

現(xiàn)代人工智能系統(tǒng)和機器學習算法在各個領(lǐng)域都取得了革命性的進步。我們注意到在計算機視覺,語音識別和自然語言處理等技術(shù)領(lǐng)域的長足進步。更進一步,這些技術(shù)進步已經(jīng)惠及我們個人生活的方方面面。個人定制數(shù)字化助理,電商平臺的推薦系統(tǒng),金融詐騙檢測,定制化網(wǎng)頁搜索和社交網(wǎng)絡(luò)訂閱以及新穎的地理位置經(jīng)濟學發(fā)現(xiàn)都得益于當前機器學習算法。

近幾年,一種稱之為深度學習的機器學習的分支已經(jīng)被證明特別有效。深度學習屬于表現(xiàn)學習算法類,它使用復雜神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),其中包含巨大數(shù)量的隱藏層。每個隱藏層包含對輸入數(shù)據(jù)進行簡單但卻是非線性轉(zhuǎn)換。給定足夠這樣的轉(zhuǎn)換模塊可以構(gòu)成非常復雜的功能模型去實現(xiàn)分類,回歸,翻譯和很多其他的事情【1】。

值得注意的是,深度學習的崛起也就是近幾年的事情,這都得益于越來越多可用的大數(shù)據(jù)集可以作為訓練樣本;得益于有效使用GPU和大量并行硬件在大數(shù)據(jù)集上訓練深度學習模型;也得益于一些新方法的發(fā)現(xiàn),比如修正線性單元(ReLU)激活函數(shù)或者退化(Dropout)作為一種正規(guī)化技術(shù)【1】【2】【3】【4】。

在深度學習算法和單獨算法模塊比如表示轉(zhuǎn)換,激活函數(shù),或者正規(guī)化方法在開始還是數(shù)學公式的時候,接下來它們必須要轉(zhuǎn)化為某種計算機程序?qū)崿F(xiàn)才能用于應(yīng)用。因此,市場上存在很多這樣的開源和商業(yè)軟件。在這些眾多的軟件中,Theano【5】,Torch【6】,scikit-learn【7】和許多其它的軟件會在本文第二部分有更詳細的評估。而Tensorflow是在2015年11月由谷歌發(fā)布的全新機器學習軟件庫【8】。根據(jù)開始公布的情況來看,Tensorflow旨在擔當在“大規(guī)?!碑悩?gòu)分布式系統(tǒng)上的“快速機器學習算法實現(xiàn)”【8】。

本文接下來將完整評估Tensorflow,并且將其放在當前機器學習的大背景下來討論。本文詳細架構(gòu)如下,第二部分將介紹機器學習軟件發(fā)展歷史,不局限于Tensorflow相似項目。接下來,第三部分將深入討論Tenorflow的計算范式。在第四部分,我們會解釋各類編程語言的編程接口。第五部分會介紹Tensorflow的調(diào)錯可視化工具。第六部分是Tensorflow和其它類似軟件庫的定性和定量分析。在最后第八部分總結(jié),第七部分對于Tensorflow的學術(shù)界和工業(yè)界使用做了研究。

二,機器學習軟件庫歷史

本章旨在提供一個機器學習軟件庫歷史和關(guān)鍵里程碑的描述。開始,我們回顧20年前一系列廣泛用于機器學習和數(shù)據(jù)分析的軟件庫。然后,我們聚焦到最近適合于深度學習的編程框架研究。圖一展示的是這一研究在時間軸上的展開。本章不會比較比較Tensorflow和這些軟件庫,因為這一部分將會在第六部分具體討論。

A. 通用機器學習

在接下來的文字,我們將會列舉和回顧一組通用機器學習軟件庫。所謂“通用”,意味著這些軟件庫用于機器學習和數(shù)據(jù)分析,并不局限于深度學習。所以,它們可能用于統(tǒng)計分析,聚類,降維分析,結(jié)構(gòu)化預測,異常檢測,淺神經(jīng)網(wǎng)絡(luò)(相對于深度神經(jīng)網(wǎng)絡(luò)而言)和其它。

讓我們從Tensorflow發(fā)布21年前的一個庫開始說起,MLC++【9】。MLC++是用C++開發(fā)的算法庫,包含了一系列數(shù)據(jù)挖掘,統(tǒng)計分析,模式識別技術(shù)的比較框架。它誕生于斯坦福大學,現(xiàn)在被Silicon Graphics Inc公司(SGI)維護。據(jù)我們所知,這是迄今為止歲數(shù)最大的機器學習庫。

排在MLC++后面的,當屬Bradski等人在2000年發(fā)布的OpenCV【10】。它主要解決計算機視覺和圖像識別問題,包括一系列人臉識別,對象識別,3D模型提取等。它遵循BSD開源,擁有C++,Python和MATLAB等多種編程接口。

另一種機器學習庫我們希望提及的是scikit-learn【7】。2008年由David Cournapeu作為谷歌編碼之夏項目的一部分開發(fā)出來。它是使用Python編寫的開源庫,基于NumPy,SciPy和matplotlib框架。它能夠用于廣泛的監(jiān)督學習和非監(jiān)督學習問題。

Accord.NET和前述庫不一樣,它是2008年使用C#開發(fā)的,除了一些機器學習算法,它還包括了用于語音識別和圖像識別的信號處理模塊?!?1】

Massive Online Analysis(MOA)是一個可以支持在線和離線大數(shù)據(jù)分析的開源庫。MOA包括了一系列用于分類,回歸,推薦系統(tǒng)和其它訓練能力。它于2010年發(fā)布,使用JAVA編程語言,由新西蘭的Waikato大學維護【12】。

Mahout是Apache軟件基金會支持的一個Java開源庫,基于Hadoop平臺,支持可伸縮的機器學習應(yīng)用。它可以憑借Hadoop分布式文件系統(tǒng)(HDFS)對于大數(shù)據(jù)集的很好支持進行分析。Mahout提供了分類,回歸和過濾算法。

Pattern在我們認可的Python機器學習庫列表之中,得益于它提供豐富的網(wǎng)頁挖掘能力。它包含了不僅僅是機器學習算法(比如,聚類,分類或者最近鄰近搜索),自然語言處理(n-gram搜索用于情感分析),還提供了網(wǎng)絡(luò)爬蟲,比如抓去Tweets或者Wiki百科的數(shù)據(jù)來幫助快速分析。它由Antwerp大學于2012年開發(fā),開源并維護。

最后一個需要介紹的是Spark MLib,也是一款開源機器學習庫,發(fā)布于2015年,看名字很容易知道,這是基于Spark開發(fā)而成分布式分析系統(tǒng)。它支持處理大規(guī)模分布式數(shù)據(jù)集,并且在集群硬件環(huán)境下進行機器訓練。它包含了分類,回歸,聚類和其它機器學習的算法【14】。

B. 深度學習

上述軟件庫能夠用于非常廣泛的機器學習,統(tǒng)計分析應(yīng)用。接下來介紹的庫在訓練深度模型方面特別有效。

首先介紹的是發(fā)布于2002年的,最古老的Torch【6】。Torch包含了一個純C++實現(xiàn)和編程接口?,F(xiàn)在,他的核心是C/CUDA實現(xiàn),對外暴露的語言是Lua腳本語言。Torch采用一個LuaJIT(實時)編譯器把Lua的函數(shù)過程連接到C語言的具體實現(xiàn)。它包括了內(nèi)部別名,數(shù)值優(yōu)化過程,神經(jīng)網(wǎng)絡(luò)模型,同時能夠產(chǎn)生通用的N維數(shù)組(張量)對象。

Theano發(fā)布于2008年【5】,是另外值得一提的庫。我們注意到Theano在機器學習社區(qū)具有極高的人氣,但是它實際上并不是機器學習庫。它只是符號化數(shù)理編程框架,比如生成計算圖,然后編譯和優(yōu)化在CPU或者GPU上運行,所以Theano更多時候只是“數(shù)理編譯器”。

Caffe是由Berkley視覺與學習中心(BVLC)維護的開源深度學習庫。它于2014年發(fā)布,并遵循BSD開源【15】。Caffe使用C++實現(xiàn),神經(jīng)網(wǎng)絡(luò)層是它的計算單元(這和Theano那些需要用戶自己定義詳細的數(shù)學公式去構(gòu)成神經(jīng)網(wǎng)絡(luò)層不同)。包含很多層的深度學習模型采用谷歌協(xié)議緩沖格式保存(GPBF)。模型能夠使用協(xié)議緩沖“語言”定義,然后通過和Python或者MATLAB已有的綁定,自動生成神經(jīng)網(wǎng)絡(luò)。Caffe特別適合于訓練卷積神經(jīng)網(wǎng)絡(luò)(CNNs,或者ConvNets)用于圖像識別領(lǐng)域。

上面介紹的機器學習庫都是使用Python,MTATLAB或者Lua定義深度學習模型,而Deeplearning4J(DL4J)則是使用Java去創(chuàng)建深度神經(jīng)網(wǎng)絡(luò)。DL4J能夠創(chuàng)建有限波資曼機,卷積神經(jīng)網(wǎng)絡(luò)和遞歸神經(jīng)網(wǎng)絡(luò)。DL4J還能夠使用Hadoop或者Spark這樣的分布式計算平臺進行工作。Adam Gibson2014年編寫的DL4J遵循Apache 2.0開源協(xié)議。

最后我們要介紹的是NVIDIA的深度學習SDK。這個SDK能夠充分利用GPU來加速計算。SDK首先提供了基于GPU的高性能深度算法(cuDNN),用于加速卷積,激活函數(shù)和張量轉(zhuǎn)換。其次,它提供了一個線性代數(shù)庫,cuBLAS。最后,cuSPARSE包含了基于GPU的高效空間矩陣運算。它可以單獨使用,也可以和其它庫聯(lián)合使用,比如Torch。

三, Tensorflow編程模型

在這一章,我們將深度討論Tensorflow的計算范式。開始,我們會研究Tensorflow的基本架構(gòu)和計算原理,解釋機器學習算法如何在Tensorflow里面使用數(shù)據(jù)流圖語言表征。接下來,我們研究Tensorflow的運行模型,也就是Tensorflow如何把Tensorflow圖轉(zhuǎn)化為運行狀態(tài)。然后,我們調(diào)查Tensorflow內(nèi)在的,針對軟硬件的不同算法優(yōu)化。最后,我們列舉一系列算法擴展,以支撐用戶在Tensorflow對于計算模型,邏輯模型訓練。

A. 計算圖架構(gòu)

在Tensorflow里面,機器學習算法被表證為計算圖。計算圖或者數(shù)據(jù)流圖是一種有向圖。有向圖的頂點或者節(jié)點代表運算過程,有向圖的邊代表運算過程之間的數(shù)據(jù)流。如下圖所示,先看左邊,輸出變量z是輸入x和y的二值運算的結(jié)果,那么畫兩條分別從x和y向z的有向邊,并且在z上標明運算加號。一個更加完整和復雜的數(shù)據(jù)流圖在右邊。下面,對于數(shù)據(jù)流圖里面的元素(operation - 算子,tensor - 張量,variable - 變量和session - 過程)進行更為詳盡的討論。

1)Operations(算子):使用圖來表示一個算法的主要好處不僅僅是直觀展示計算模型之間的依賴和關(guān)聯(lián),而且能夠更普適的定義運算節(jié)點。在Tensorflow里,node(節(jié)點)代表著算子,也就是一種運算,更精確來說,代表了輸入的數(shù)據(jù)在有向圖上,如何流經(jīng)這個節(jié)點【8】。一個算子可以是0到多個輸入,也能產(chǎn)生0到多個輸出。因此,一個算子代表一個數(shù)學等式,一個變量,一個常量,一個有向控制流,一個文件I/O操作或者甚至是一個網(wǎng)絡(luò)通訊連接端口。在算子可以表達為一個常量或者變量不是像表達成一個函數(shù)那樣直觀,但是一個常量可以被當成一個沒有輸入,而且輸出恒定的運算。相似的情況也適用于表征一個變量,也就是沒有輸入,輸出當前狀態(tài)或者當前變量的值。

任何算子必須要嚴格的定義和實現(xiàn)。在論文【8】的研究,任何一種實現(xiàn)被當作一個算子的核函數(shù)。一種特定的核函數(shù)的具體編程都是針對某種硬件,比如CPU或者GPU的運算。

2)Tensors(張量):在Tensorflow里面,代表數(shù)據(jù)流從一個算子流向另一個算子的邊稱之為張量。一個張量是一個具有固定類型同類數(shù)據(jù)的多維集合。張量維度也稱為rank(階)。張量的形狀(shape)描述張量大小的元祖(tuple)。比如,對于每一個維度的元素個數(shù)。從數(shù)學的觀點來看,張量是一個二維矩陣加一個表達張量階的一維向量或者標量的生成物。

從計算圖的觀點來看,張量是表征通向輸出的算子的符號把手(symbolic handle)。在內(nèi)存里,張量本身并不包含和存儲數(shù)據(jù),但是它提供了張量代表的數(shù)據(jù)訪問的接口。在Tensorflow里面創(chuàng)建一個算子的時候,比如x+y,返回一個張量對象。然后,這個張量可能作為其他計算的輸入,從而張量是連接源算子和目的算子的邊?;谶@樣的認知,數(shù)據(jù)在Tensorflow的圖中川流不息。

除了通常意義的張量,Tensorflow還支持一種稱之為稀疏張量(SparseTensor)的數(shù)據(jù)結(jié)構(gòu)。這是一種空間有效字典類的數(shù)據(jù)表證,也就是大量零值的稀疏張量。

3)Variables(變量):在通常情況,比如做隨機梯度下降的單次運算的時候,機器學習模型的圖會從開始到結(jié)束反復運算多次。在兩次調(diào)用之間,圖中主要的張量并不會被保存。但是整體上對于圖的求值是需要保存狀態(tài)的,比如神經(jīng)網(wǎng)絡(luò)的權(quán)重和參數(shù)。因此,變量正是為了滿足這一需求而創(chuàng)建的算子,能夠被添加到計算圖中。

變量可以看成是在內(nèi)存中持久不變的張量副本。因此,變量的定義需要形狀和固定數(shù)據(jù)類型兩個特征。Tensorflow提供了一系列賦值函數(shù)完成圖運算。

在Tensorflow的圖中創(chuàng)建一個變量節(jié)點的時候,需要定義相應(yīng)的張量,這樣在圖運行時,變量可以隨之初始化。變量的形狀和數(shù)據(jù)類型也來自于這個初始器。有趣的是,變量自己并不存儲這個初始的張量,相反構(gòu)造一個變量會增加三種不同的節(jié)點:

1)變量節(jié)點,保存持久狀態(tài)。

2)保存初始值的算子,通常是一個常量。

3)初始器算子,在圖求值的時候把初始值賦值給變量張量。

一個例子如下圖所示:三個節(jié)點代表變量定義。第一個變量v是一個變量的張量值在內(nèi)存中的持久副本。第二個變量i是給變量提供初始值(可以是任意張量)的節(jié)點。最后一個賦值節(jié)點把初始值賦給變量,在賦值節(jié)點產(chǎn)生一個新的張量具有初始值的變量v‘。這樣,v'可能作為另外算子的一個輸入。

4)Session(會話):在Tensorflow里面,算子的運算和張量的估值會在一定的上下文中進行,我們稱之為Session(會話)。會話的責任之一就是將分配和管理資源的工作封裝起來,比如緩存變量。更進一步來看,Tensorflow庫里面的Session接口提供了一個run函數(shù),作為整個圖計算的執(zhí)行入口。這個方法將輸入節(jié)點帶入整個圖計算的過程,并且根據(jù)圖定義返回相應(yīng)的結(jié)果。另外,一個可選的映射,即從任意節(jié)點到相應(yīng)替代值的映射,被稱為feed nodes(反饋節(jié)點),可能也被run調(diào)用【8】。

在調(diào)用run的時候,Tensorflow將會出輸出節(jié)點開始反向分析計算圖的節(jié)點依賴,計算所有節(jié)點的傳遞閉包。這些節(jié)點可能被分配到一個或者多個物理計算單元(CPU,GPU等),這些計算單元可以在一臺或者多臺機器上。分配的規(guī)則由Tensorflow的placement algorithm(分配算法)定義。這個算法會在本文后面部分談到。此外,因為存在節(jié)點評估順序的特定顯式可能性,姑且稱為控制依賴關(guān)系,執(zhí)行算法將確保這些依賴關(guān)系不變。

B. 執(zhí)行模型

如剛剛討論的那樣,對于執(zhí)行各種計算圖元素的組成,TensorFlow劃分其任務(wù)在四個不同的組中實現(xiàn):客戶端,主控端,一組工作進程和一些設(shè)備。 當客戶端通過會話的run調(diào)用請求評估一個TensorFlow圖,這個請求被發(fā)送到主控端,主控端將任務(wù)委托給一個或多個工作進程處理和協(xié)調(diào)它們的執(zhí)行。 每個工作進程隨后負責一個或多個設(shè)備真實的運算和處理操作。

在這個模型中,有兩個擴展度。 第一擴展度是關(guān)于執(zhí)行圖運算機器的數(shù)量。 事實上,第二擴展度指的是在每臺機器上,可能會有更多設(shè)備,例如,五個獨立的GPU和/或三個CPU。 為此,存在兩個“版本”的TensorFlow,一個用于在單個機器上本地執(zhí)行(但可能有許多設(shè)備),一個支持分布式在許多機器和許多設(shè)備上實現(xiàn)。

上圖展示了執(zhí)行模型和響應(yīng)擴展度。而且Tensorflow在開始發(fā)布的時候,確實只公布了單機版本,而多機版本是在2016年的4月13日才姍姍來遲【16】。

1)Devices(設(shè)備):設(shè)備是在TensorFlow執(zhí)行模型中最小,最基本的實體。 上圖中的所有節(jié)點,也就是每個算子的內(nèi)核,最終都必須是映射到要執(zhí)行的可用設(shè)備。 在實際執(zhí)行過程中,設(shè)備通常是CPU或GPU。 然而,TensorFlow能夠支持更多種類的物理執(zhí)行單元。 例如,在2016年5月,谷歌宣布其定制的ASIC(專用集成電路)張量處理單元(TPU),是專門用于快速張量計算[17]。 因此,Tensorflow是可以容易地集成新出現(xiàn)的設(shè)備類新型硬件。

為了整體評估在某個設(shè)備上的節(jié)點,主控端生成相應(yīng)的工作進程。 作為工作進程可以在單個機器上管理一個或多個設(shè)備,設(shè)備是不僅通過名稱標識,還標識其所在工作進程組的索引。 例如,特定組中的第一CPU可以由字符串“/ cpu:0”標識。

2)placement algorithm(分配算法):為了決定哪一個節(jié)點分配給那一個設(shè)備,Tensorflow使用了一種特定分配算法。該算法模擬計算圖的運算和遍歷從輸入張量到輸出張量的全部節(jié)點。在遍歷節(jié)點過程中,要決定哪一個可用設(shè)備D={d1,d2,...dn}運行給定節(jié)點v,算法使用一個成本模型Cv(d)。這個成本模型考慮四種信息來決定最優(yōu)設(shè)備d = arg mind∈D Cν(d):

1)在給定設(shè)備上是否存在該節(jié)點的實現(xiàn)(核函數(shù))。比如,如果任何一個GPU上都不存在某種特定算子,那么選擇任意GPU的成本都是無限的。

2)估計一個節(jié)點的輸入和輸出丈量的大小(按字節(jié)計算)。

3)給定設(shè)備對于核函數(shù)的期望計算時間。

4)對于輸入丈量到相應(yīng)算子跨設(shè)備或者跨機器的傳輸成本進行啟發(fā)式估算,萬一該節(jié)點已經(jīng)賦值的輸入張量所在設(shè)備和當前設(shè)備并不一樣。

3)cross-device execution(跨設(shè)備運行):只要是用戶擁有多個設(shè)備,Tensorflow通常都會把節(jié)點分配到這些設(shè)備上去。這個過程是通過把節(jié)點分類,然后一類分配到一個設(shè)備。這樣分配的話,必須處理跨設(shè)備分配的節(jié)點依賴問題。讓我們考慮A和B這樣兩個設(shè)備,其中節(jié)點v在設(shè)備A上。如果v的輸出張量作為另外兩個算子α, β的輸入,同時α, β在設(shè)備B上。那么就存在從A到B的跨設(shè)備的邊ν → α 和 ν → β。如下圖所示:

在實際運行中,需要使用一些傳輸手段完成v的輸出張量從A設(shè)備,比如GPU,到設(shè)備B,比如CPU的過程。如下圖所示,send和recv兩類節(jié)點被生成完成這個傳輸過程。

最后,Tensorflow使用“規(guī)范化”來優(yōu)化(send,recv)對。在上圖所示的例子中,我們看到兩個recv節(jié)點,分別連接α, β。然而,一種等價的,但是更為有效的辦法就是在設(shè)備B上只運行一個recv,如下圖所示。

C. 執(zhí)行優(yōu)化

為了保證Tensorflow運行模型的最優(yōu)化,一系列優(yōu)化算法被內(nèi)置其中。本章節(jié)將重點介紹三種優(yōu)化方法:常用子圖消減法,執(zhí)行時序安排法和損失壓縮法。

1)Common Subgraph Elimination(常用子圖消減法):常用子表證消減法是眾多現(xiàn)代編譯器采用的優(yōu)化算法,憑借合并同類計算項的辦法,編譯器可以將相同計算的多次實例合并成一個實例。結(jié)果會保存在一個臨時變量,這樣可以重復使用該結(jié)果。在Tensorflow圖的運算中,也會出現(xiàn)相似的情形,一個算子對于相同輸入會被重復調(diào)用多次。如果就這樣直接運算,那么效率是非常低下的,同時大量的內(nèi)存占用也是不合理的。因此,Tensorflow也應(yīng)用這種同類消減法,或者更恰當?shù)拿枋鍪腔谇按螆?zhí)行的子圖消減法。對于這種算法,遍歷計算圖,凡是遇到兩個或者更多對于同樣輸入張量的同種類型的算子可以通過規(guī)范化合并成一個子圖。此算子的輸出張量然后會被轉(zhuǎn)移到所有相應(yīng)依賴的節(jié)點去。下圖給出了消減的一個示例。

2)Scheduling(時序安排法):一個簡單而強大的優(yōu)化是盡可能晚地調(diào)度節(jié)點執(zhí)行。 確保操作結(jié)果僅在最小所需時間段內(nèi)保持在存儲器中,由此減少了存儲器峰值消耗,并且因此可以大大提高系統(tǒng)的整體性能。文獻 [8]的作者指出,這對于諸如GPU之類的設(shè)備尤為重要,因為它們的存儲器資源很少。 此外,仔細安排的調(diào)度還涉及激活send和recv節(jié)點,這里面不僅存儲器而且網(wǎng)絡(luò)資源都被作為競爭資源。

3)Lossy Compression(損失壓縮法):諸如分類,回歸或者其它機器學習算法的主要目的是建立穩(wěn)健的模型。我們這里說“穩(wěn)健”的意思是指理想的優(yōu)化過的模型算法不會因為偶然噪聲信號改變響應(yīng)輸出。因此,算法對于計算數(shù)值的精度要求就會下降,比如使用16比特運算就可以達到32比特計算的效果,但是很明顯這樣不僅僅是節(jié)約了小數(shù)點后位數(shù),也極大降低了計算開銷?;谶@個原則,在Tensorflow里面,把節(jié)點轉(zhuǎn)化為計算圖的內(nèi)部加法采用了類似的方法。當數(shù)據(jù)通訊跨設(shè)備或者機器的時候,在發(fā)送端將32位浮點數(shù)字轉(zhuǎn)化為截斷的16位表示,在接收端被截斷的數(shù)字被簡單的通過補零法恢復成32位,而不是使用取整運算【8】。

D. 和基礎(chǔ)編程模型相關(guān)部分

討論了Tensorflow的基礎(chǔ)計算范式和執(zhí)行模型之后,我們將繼續(xù)討論另外三種和創(chuàng)建機器學習算法高度相關(guān)的高級主題。第一,我們討論Tensorflow如何處理被許多機器學習算法廣泛使用的梯度反饋(gradient back-propagation)的。然后,我們研究Tensorflow是如何控制數(shù)據(jù)流的。最后,我們簡單談一下檢查點技術(shù)(checkpoint),因為在使用大型模型的時候非常有用的一種技巧和技術(shù)。

1)Back-Propagation Nodes(反向傳播節(jié)點):在相當多的深度學習和其它機器學習算法里面,計算計算圖中特定節(jié)點相對其他一個或者多個節(jié)點的梯度是非常有必要的。比如,在神經(jīng)網(wǎng)絡(luò)中,我們可能通過將給定樣本進行一系列非線性轉(zhuǎn)換來計算模型的成本函數(shù)c。如果神經(jīng)網(wǎng)絡(luò)包含兩個隱藏層,其表證函數(shù)f(x;w) =fx(w)和g(x;w) =gx(w),w是內(nèi)部權(quán)重。我們可以把其對應(yīng)該樣本的成本函數(shù)表示成c = (fx?gx)(w) =fx(gx(w))。通常我們會做微分dc/dw來求相應(yīng)的權(quán)重w,然后用得到的權(quán)重去更新原有權(quán)重。這種計算在反向傳播算法是通過反向遍歷圖去計算[fx(gx(w))]′=fx′(gx(w))·gx′(w)完成的。

在文獻【18】中,描述了兩種計算反向傳播梯度的算法。第一種稱為symbol-to-number differentiation(圖數(shù)差異法)。它是接受一組輸入值,然后計算這組輸入的梯度數(shù)值。它通過明確的前向遍歷圖計算成本函數(shù),然后再反向遍歷計算剃度。第二種稱為symbol-to-symbol derivatives(符號到符號導數(shù)法),這是和Tensorflow更相關(guān)的算法,在文獻【8】中被稱為automatic gradient computation(自動梯度計算法)。在這種情況下,梯度不是通過反向傳播算法的顯式實現(xiàn)來計算的。 相反,它將特殊節(jié)點添加到計算圖中,然后根據(jù)計算鏈規(guī)則計算該計算圖每個算子的梯度。 為了進行反向傳播運算,然后必須通過圖評估引擎簡單地像任何其它節(jié)點那樣執(zhí)行這些節(jié)點。 因此,此方法不會求導,而僅計算這些值的符號句柄。

當Tensorflow需要計算一個特定節(jié)點v相對其它節(jié)點α的梯度時,它會從v到α反向遍歷圖。在遍歷中遇到 的每一個算子o表示依賴α的函數(shù)和產(chǎn)生輸出張量連接集合(ν?...?o?...)(α)的一個連接。因此,Tensorflow為每一個選取前一個連接梯度,并且乘以它自己梯度的算子o添加梯度節(jié)點。在遍歷的最后,有一個節(jié)點帶有符號句柄表示目標倒數(shù)dv/dα,即隱含實現(xiàn)了反向傳播算法?,F(xiàn)在可以很清楚的看到,在符號到符號方法僅僅是另一種沒有任何例外的算子。下圖展示了一張計算圖在梯度節(jié)點增加前后的樣子。

在文獻【8】中提到符號到符號導數(shù)法可能產(chǎn)生相當可觀的計算開銷,包括內(nèi)存的開銷。究其原因,需要理解兩組鏈式規(guī)則的等價公式。第一組公式會重用之前計算結(jié)果需要為了前向傳播的需要,保存相應(yīng)的結(jié)果。對于等式1中的任意函數(shù)f,g,h:df/dw=f′(y)·g′(x)·h′(w)withy=g(x),x=h(w) (1)

對于計算鏈式規(guī)則的第二種可能公式已經(jīng)表明,每個函數(shù)需要重新計算它們所有的參數(shù)并且調(diào)用它們依賴的每一個函數(shù)。該公式表示成:df/dw=f′(g(h(w)))·g′(h(w))·h′(w) (2)

根據(jù)文獻【8】,Tensorflow當前使用第一組公式。假定如果不采用這種方法,并且考慮到這個連接可能包括數(shù)百或數(shù)千個操作,則對于此連接的幾乎每個連接必須重新計算最內(nèi)層函數(shù),因此這種選擇看起來是合理的。 然而,從另一方面來看,在存儲器中長時間保存張量也不是最佳的,尤其是在諸如GPU的設(shè)備上,其存儲器資源是稀缺的。 對于等式2,由張量保持的存儲器在理論上可以在其已被其圖依賴性處理時被釋放。 因此,根據(jù)文獻[8]的說法,TensorFlow的開發(fā)團隊稱,重新計算某些張量而不是將它們保留在內(nèi)存中的做法可能是未來進行性能改進的方向。

2)控制流:某些機器學習算法會從執(zhí)行流控制中受益,即只在特定條件下執(zhí)行特定流,或者僅僅執(zhí)行固定次數(shù)。對此,Tensorflow提供了一組流控制的基本體,包括if條件跳轉(zhuǎn)和loop循環(huán)。循環(huán)條件控制的存在是因為Tensorflow計算圖可能是循環(huán)的。如果對于循環(huán)的次數(shù)是已知或者固定的,那么循環(huán)體可以被展開成非循環(huán)的計算序列【5】。但是為了支持可變迭代,Tensorflow需要強制跳轉(zhuǎn)到如文獻【8】描述的一組環(huán)運算。

當引入控制流需要特別注意的是在有反向傳播的場景。 在處理條件控制的情況下,如果if操作返回一個或另一個張量,則必須知道在向前傳播期間節(jié)點采取哪個分支,使得梯度節(jié)點僅被添加到該分支。 此外,當循環(huán)體(其可以是小圖)被執(zhí)行特定次數(shù)時,梯度計算不僅需要知道執(zhí)行的迭代的次數(shù),而且還需要訪問所產(chǎn)生的每個中間值。 這種通過反向循環(huán)計算梯度的技術(shù)在文獻[5]中稱為反向傳播時間。

3)Checkpoints(檢查點):Tensorflow另一個基本編程模型的擴展就是檢查點技術(shù)的應(yīng)用。檢查點技術(shù)允許模型參數(shù)可以被序列化到文件,以備再次運行模型的時候可以從文件中恢復模型參數(shù)和運行變量。因此可以在計算圖中增加Save節(jié)點去保存相應(yīng)變量的張量。當然,一個變量也可能連接到restore算子去恢復相應(yīng)的張量。這種方法對于那些需要長時間才能訓練的模型,對于模型計算容錯性考量都是很好的技術(shù),特別是在分布式環(huán)境【8】。

四. Tensorflow的編程接口

在討論了Tensorflow計算模型之后,我們現(xiàn)在聚焦到更為實際的編程接口。我們先介紹可用的編程語言接口,再使用一個例子講解Python API的使用。最后,我們概括Tensorflow API的格局和怎么能夠快速創(chuàng)建算法原型。

A. 接口

Tensorflow擁有C++和Python兩種編程接口,允許用戶調(diào)用后端功能。Python API提供了豐富和完整的創(chuàng)建和運行計算圖的編程接口,而C++的接口相對有限和與后端功能實現(xiàn)耦合度太高,僅僅允許去執(zhí)行計算圖和序列化圖到谷歌協(xié)議緩沖格式。對于創(chuàng)建圖的C++接口在文章發(fā)表的時候還很不完善。

值得注意的是,Tensorflow的API和NumPy有很好的集成。因此,我們可以看到Tensorflow的數(shù)據(jù)類型tensor和NumPy的ndarrays在很多應(yīng)用場合都是可以互換的。

B. 示例解讀

接下來的幾個章節(jié),我們將一步一步的解讀一個Tensorflow的真實示例。我們將訓練一個帶有一個輸入和一個輸出的簡單的多層感知器(MLP),它將用于識別MNIST數(shù)據(jù)集中的手寫字符。在這個數(shù)據(jù)集中,樣本時28x28像素的手寫字符從0-9。我們將這些字符轉(zhuǎn)換成784灰度像素扁平的向量。對于每個樣本的標簽是相應(yīng)字符的數(shù)字。

我們從加載輸入數(shù)據(jù)開始解讀。這里數(shù)據(jù)已經(jīng)被處理好成為我們需要的格式,只需要調(diào)用read函數(shù)加載數(shù)據(jù)到內(nèi)存。進一步來看,我們設(shè)置one_hot=True來指定是否使用一個10維向量(d1,。。。,d10)的轉(zhuǎn)置來表征某一個字符,即所有維度數(shù)字是0,只有表征該字符的位置是1。

importtensorflow as tf

# Download and extract the MNIST data set.

# Retrieve the labels as one-hot-encoded vectors.

mnist = mnist_data.read('/tmp/mnist', one_hot=True)

接下來,我們通過調(diào)用tf.Graph創(chuàng)建一個新計算圖。為了給這個圖增加算子,我們必須把這個圖注冊為缺省圖。在TensorflowAPI和庫設(shè)計里面,新的算子總是掛在缺省圖上。相應(yīng)代碼如下:

# Create a new graph

graph = tf.Graph()

# Register the graph as the default one to add nodes

with graph.as_default():

# Add operations ...

我們現(xiàn)在準備通過增加算子來生成計算圖。讓我們先增加兩個占位節(jié)點examples和labels。占位者是一種特殊變量,在圖運算的時候必須被確切的張量賦值。也就是說,上面創(chuàng)建的占位者必須在Session.run()被調(diào)用的時候,被feed_dict參數(shù)傳進來的張量所取代。對于每一個這個的占位者,我們定義它的形狀和數(shù)據(jù)類型。Tensorflow在這里可以使用None來描述占位者形狀的第一個維度。這就是為未來給此占位者賦值一個在此維度大小可變的張量。對于examples的列大小,我們指定每一幅圖的特征數(shù),即28 x 28 = 784個像素。labels占位者應(yīng)該有10列,代表著我們在上面定義的10維字符分類向量。

# Using a 32-bit floating-point data type tf.float32

examples = tf.placeholder(tf.float32, [None, 784])

labels = tf.placeholder(tf.float32, [None, 10])

給定一個example矩陣X屬于集合R是nx784,意味著包含n個圖像,學習算法將使用仿射變換X.W+b,這里W是一個784x10的權(quán)重矩陣,b是10維偏置向量。這個變換的結(jié)果產(chǎn)生Y是nx10的矩陣,包含我們模型對于每一個樣本圖像識別的結(jié)果。這些結(jié)果是一些任意數(shù)值而不是概率分布。為了轉(zhuǎn)換它們到一個有效概率分布,在給定似然Pr[x=i],即第x樣本圖像是數(shù)字i的概率,我們使用softmax函數(shù),公式和相應(yīng)代碼如下:

# Draw random weights for symmetry breaking

weights = tf.Variable(tf.random_uniform([784, 10]))

# Slightly positive initial bias

bias = tf.Variable(tf.constant(0.1, shape=[10]))

# tf.matmul performs the matrix multiplication XW

# Note how the + operator is overloaded for tensors

logits = tf.matmul(examples, weights) + bias

# Applies the operation element-wise on tensors

estimates = tf.nn.softmax(logits)

接下來,我們計算我們的目標函數(shù),產(chǎn)生模型在當前權(quán)重W和偏差b下的成本或者損失。公式H(L,Y)i=?jLi,j·log(Yi,j)計算我們預測的結(jié)果和訓練樣本實際結(jié)果之間的交叉熵。更精確而言,我們考慮的是所有訓練樣本的交叉熵的均值作為成本或者損失。

# Computes the cross-entropy and sums the rows

cross_entropy = -tf.reduce_sum(labels*tf.log(estimates), [1])

loss = tf.reduce_mean(cross_entropy)

現(xiàn)在,我們有了目標函數(shù),就可以進行隨機梯度下降計算去更新我們模型的權(quán)重矩陣。為此,Tensorflow提供了GradientDescentOptimizer這個類實現(xiàn)這一過程。該類使用算法的學習速度來初始化,同時提供算子minimize來處理我們的成本或損失張量。這就是我們在Session環(huán)境里訓練模型需要反復迭代的算子。

# We choose a learning rate of 0.5

gdo = tf.train.GradientDescentOptimizer(0.5)

optimizer = gdo.minimize(loss)

最后,我們就可以實際訓練模型了。在Tensorflow里,我們需要進入一個會話環(huán)境,使用tf.Session來管理會話。通過Session,我們訓練我們的模型,執(zhí)行計算圖上的算子。我們有幾種調(diào)用方法,最常見的方式是調(diào)用Session.run(),然后傳遞一組張量給它。或者,我們也可以直接在張量上調(diào)用eval()和算子上run()。在評估算子之前,我們必須確保我們圖變量被初始化了。理論上,我們可以通過調(diào)用Variable.initializer算子來初始化每一個變量。然而,最常見的辦法是調(diào)用tf.initialize_all_variables()方法去一次性初始化所有變量。然后我們就可以迭代幾次隨機梯度下降,每一次我們選取一些樣本圖像和標簽,傳遞給模型去計算成本或損失。最后,我們的成本或損失會越來越小(我們希望如此):

with tf.Session(graph=graph) as session:

# Execute the operation directly

tf.initialize_all_variables().run()forstepinrange(1000):

# Fetch next 100 examples and labels

x, y = mnist.train.next_batch(100)

# Ignore the result of the optimizer (None)

_, loss_value = session.run(

[optimizer, loss],

feed_dict={examples: x, labels: y})

print(’Loss at step {0}: {1}’.format(step, loss_value))

這個例子完整的代碼參見附錄。

C. 抽象與封裝

你可以已經(jīng)注意到構(gòu)建模型和訓練的過程是需要花費大量的開銷在創(chuàng)建一個非常簡單的兩層網(wǎng)絡(luò)。通過深度學習的名稱“深度”二字,就隱含了,你需要使用攜帶大量隱藏層的深度神經(jīng)網(wǎng)絡(luò)。因此,每一次構(gòu)建模型都需要花這么多時間構(gòu)建權(quán)重矩陣,偏置矩陣,計算矩陣乘法,加法,和應(yīng)用非線性激活函數(shù)的神經(jīng)網(wǎng)絡(luò)是效率低下的,因此,我們需要抽象和封裝這一過程。幸好,我們可以使用一些開源的庫來完成這一過程,比如PrettyTensor,TFLearn和Keras。下面我們會分別論述PrettyTensor和TFLearn。

1)PrettyTensor:這是谷歌開發(fā)的高級編程接口,主要的是通過Builder模式來調(diào)用Tensorflow的API。它允許用戶把Tensorflow的算子和張量封裝進干凈的版本,然后迅速將任意層串接起來。比如,它可以用一行代碼完成一個輸入張量傳輸?shù)揭粋€全連接(稠密)神經(jīng)網(wǎng)絡(luò)層。下面的樣例代碼顯示了從創(chuàng)建一個占位者到初始化,到創(chuàng)建三層網(wǎng)絡(luò)到最后輸出softmax的一個分布。

examples = tf.placeholder([None, 784], tf.float32)

softmax = (prettytensor.wrap(examples)

.fully_connected(256, tf.nn.relu)

.fully_connected(128, tf.sigmoid)

.fully_connected(64, tf.tanh)

.softmax(10))

2)TFLearn:這是另一個基于Tensorflow本體的封裝庫,它有高度封裝的神經(jīng)網(wǎng)絡(luò)層和層連接API。而且,它比PrettyTensor一定要通過Session建立訓練和評估模型更進一步,它可以直接添加訓練樣本和標簽來訓練模型。在TFLearn里面,有創(chuàng)建完整神經(jīng)層次的函數(shù),有返回原始Tensorflow對象的函數(shù),有混合Tensorflow本體代碼調(diào)用的編程。比如,我們可以取代Tensorflow的輸出層,自己完整構(gòu)建它,但是依然保持其它部分不發(fā)生改變。下面10行代碼完成了附錄65行代碼才能完成的功能。

importtflearn

importtflearn.datasets.mnist as mnist

X, Y, validX, validY = mnist.load_data(one_hot=True)

# Building our neural network

input_layer = tflearn.input_data(shape=[None, 784])

output_layer = tflearn.fully_connected(input_layer,

10, activation=’softmax’)

# Optimization

sgd = tflearn.SGD(learning_rate=0.5)

net = tflearn.regression(output_layer,

optimizer=sgd)

# Training

model = tflearn.DNN(net)

model.fit(X, Y, validation_set=(validX, validY))

五. Tensorflow圖的可視化

深度學習模型通常使用錯綜復雜的神經(jīng)網(wǎng)絡(luò)。比如,文獻【19】描述的谷歌Inception模型就是一個有36000個獨立單元的卷積神經(jīng)網(wǎng)絡(luò)。而文獻【8】描述的某種長短時記憶模型(LSTM)用到了15000個節(jié)點。為了使用和調(diào)優(yōu)如此復雜的網(wǎng)絡(luò),必須依賴強有力的可視化工具。Tensorboard是Tensorflow的可視化儀表盤。本章節(jié)將講述Tensorboard的功能。

A. Tensorboard的特性

Tensorboard的核心特性就是構(gòu)建明細易懂計算圖的可視化界面。如下圖例子可以看到Tensorboard是如何展示計算圖的。

name scope(命名空間)是Tensorflow里面一個重要可視化分類方法。它可以把同屬于一個命名空間的算子,關(guān)系,輸入和輸出顯示在同一個方框圖內(nèi)。下圖展示了,從上圖擴展一個layer1命名空間的詳細算法細節(jié)。

另外,Tensorboard允許用戶追蹤單個變量在訓練過程中的變化情況。你可以附加兩類總結(jié)算子到計算圖上去生成報告(scalar summaries和histogram summaries)。Scalar summaries顯示的是張量伸縮的進度圖,也就是在某次訓練迭代的采樣數(shù)據(jù)。這樣你可以看到訓練的精確度和損失變化情況。Histogram summaries節(jié)點允許用戶去追蹤數(shù)值分布情況,比如神經(jīng)網(wǎng)絡(luò)的權(quán)重或者softmax估值分布。下圖展示了這兩種報告。

我們注意到Tensorboard采用了網(wǎng)頁交互形式。一旦你的計算圖被加載進來,你就可以觀察模型,監(jiān)控算子運行。具體的Tensorboard在線演示可以在這里找到:https://www.tensorflow.org/tensorboard/index.html

B. Tensorboard的實操

為了把Tensorboard整合到你的Tensorflow代碼,你需要至少做三步。第一,你需要使用命名空間來規(guī)劃你的節(jié)點。第二,你需要給你的算子增加某種類型的報告。最后第三部,你需要調(diào)用SummaryWriter去把Summaries得到的張量寫到文件中去。與其分別去寫每一個summaries,還不如調(diào)用tf.merge_all_summaries()整合所有的summaries,然后一次性寫入文件。下面展示了Tensorboard的樣例代碼。

with tf.name_scope(’Variables’):

x = tf.constant(1.0)

y = tf.constant(2.0)

tf.scalar_summary(’z’, x + y)

merged = tf.merge_all_summaries()

writer = tf.train.SummaryWriter(’/tmp/log’, graph)

with tf.Session(graph=graph):forstepinrange(1000):

writer.add_summary(

merged.eval(), global_step=step)

六. 比較其它深度學習框架

除了Tensorflow,我們還能找到其它一些深度學習框架。人氣比較高的有Theano,Torch和Caffe。在這一章,我們會探索這些框架和Tensorflow的異同點,進行一系列定性和定量的分析。

A. 定性分析

下面我們分別比較上述三種深度學習框架和Tensorflow的差異。下圖則是匯總了這個比較。

1)Theano:在我們需要討論的三種Tensorflow的替代框架中,Theano是最像Tensorflow的。如同Tensorflow一樣,Theano的編程模型也是聲明式而不是命令式的基于計算圖。而且,Theano也使用符號差異化。然后Theano有一個比較長時間的圖編譯時間,因為它需要把Python代碼轉(zhuǎn)化為C++/CUDA代碼【5】。一方面,這是因為Theano采用了很多高級圖優(yōu)化的算法【5】,而Tensorflow僅僅是做了子圖消減優(yōu)化。對比Tensorboard, Theano的可視化工具可以用可憐來形容。它除了輸出一些可讀的文字來表示圖或靜態(tài)圖像,它還需要一個插件來生成類似交互式網(wǎng)頁可視化,剩下來的東西,Theano就是泛善可陳了。

2)Torch:Torch和Tensorflow根本不同的地方是Torch是C/CUDAde后端實現(xiàn),加上Lua的前端編程接口。Lua確實是相當快的腳本語言,可以快速構(gòu)建原型系統(tǒng),但是相對于Python,它算是非主流。雖然Lua 具備各種性能和功能上的優(yōu)勢,但是對于工業(yè)界而言,對比Tensorflow的Python API而言,就顯得曲高和寡了。除了編程語言的考量,Torch的編程模型也和Tensorflow不同。它采用命令式編程,也不聲明計算圖。這就要求程序員還要仔細安排算子執(zhí)行的順序。這也暗示了Torch在前向和反向傳播計算梯度的時候,是用符號到數(shù)值而不是符號到符號差異化來優(yōu)化。

3)Caffe:Caffe和Tensorflow有著天壤之別。Caffe的模型創(chuàng)建擁有MATLAB和Python編程接口,主要使用谷歌的協(xié)議緩沖語言,這樣帶來和Python截然不同的編程體驗。另外,在Caffe里面的基本構(gòu)建單元是神經(jīng)網(wǎng)絡(luò)的層,而不是Tensorflow里面的算子。這樣Tensorflow算是更為底層的框架。和Torch相似,Caffe也不是專注于構(gòu)建計算圖,或者符號。所以計算導數(shù)是通過符號到數(shù)值的方法。Caffe特別適合于開發(fā)卷積神經(jīng)網(wǎng)絡(luò),用于圖像識別任務(wù)。但是,它就沒有Tensorflow那樣在神經(jīng)網(wǎng)絡(luò)領(lǐng)域具備普適性。比如Caffe在架構(gòu)上不支持循環(huán)架構(gòu),而這時RNN,LSTM這樣神經(jīng)網(wǎng)絡(luò)的基本構(gòu)造。另外,Caffe也不支持分布式系統(tǒng)。

B. 定量分析

接下來,我們會對這幾種框架做定量分析來,同時給出深度學習框架評估的整體發(fā)展趨勢。

文獻【20】的研究是由博世研發(fā)中心在2016年3月進行的,他們對比了Tensorflow,Torch,Theano和Caffe這幾種不同的神經(jīng)網(wǎng)絡(luò)架構(gòu)。他們在Intel Xeon E5-1650 v2 CPU @ 3.50 GHz and an NVIDIA GeForce GTX Titan X/PCIe/SSE2 GPU這樣配置的機器上安裝Ubuntu14.04,然后跑LeNet CNN模型【21】來看不同的框架的性能如何。他們特別留意神經(jīng)網(wǎng)絡(luò)的前向傳播速度,因為他們相信這和框架部署策略有關(guān);還有反向傳播速度,這是和訓練模型性能相關(guān)。我們摘要了他們結(jié)論如下表,這個結(jié)果是在兩種情況下得到的,(a)是一個CPU跑12個線程,(b)是GPU。從結(jié)果來看,有趣的是Tensorflow無論是在CPU還是在GPU都跑不過Torch。最有意思的是Tensorflow在跑GPU的時候成績掉的很厲害,是倒數(shù)第一。文獻【20】的作者注意到這可能是由于測試Tensorflow使用的是NVIDIA的cuDNNv2,而其他庫用的是v3. 他們在文中強調(diào),這么做是因為Tensorflow的官方文檔建議這么配置cuDNN的版本。

我們能夠拿到的第二個測試來源是文獻【22】卷積神經(jīng)網(wǎng)絡(luò)評測平臺的結(jié)果,你可以在github上找到他們。它是由Facebook的一個AI研究工程師Soumith Chintala維護的。我們參考的結(jié)果是2016年五月25日提交的。Chintala提交了圍繞卷積神經(jīng)網(wǎng)絡(luò)的許多框架的實現(xiàn),當然包括Tensorflow,Torch和Caffe。Theano沒有參加評測,所以我們這里看不到它的有關(guān)數(shù)據(jù)。該作者聲稱的硬件配置是6-core Intel Core i7-5930K CPU @ 3.50GHz配有an NVIDIA Titan X graphics chip,跑的是Ubuntu14.04。該評測也分別給出了正向傳播和反向傳播的速度如下表:

不出意料,Tensorflow是僅次于Torch的框架。最后我們來看一下文獻【5】的評測,這是由Theano開發(fā)團隊在2016年5月9日提交的報告。除了CNN模型之外,他們還測試了之前我們提到的AlexNet架構(gòu),測試還包括了在Penn Treebank【24】上跑LSTM的結(jié)果。他們的評測針對小模型(200個節(jié)點的單隱藏層,每個序列長20),統(tǒng)計每秒處理多少單詞;針對大模型(兩個650個節(jié)點的隱藏層,序列長為50)。在文獻【5】還提到一個中等模型的測試,這里我們不做討論,評測結(jié)果如下圖所示:

這個結(jié)果是在硬件配置NVIDIA Digits DevBox with 4 Titan X GPUs and an Intel Core i7-5930K CPU的機器上跑出來的。,而且他們給所有框架使用的都是cuDNN v4。Caffe的運行結(jié)果沒有在列。在他們的評測結(jié)果里,Tensorflow在小模型表現(xiàn)最好,大模型稍差。這個表格來源于文獻【5】。

當Tensorflow剛剛發(fā)布的時候,表現(xiàn)奇差,整個深度學習社區(qū)都表示失望。隨后,不斷推出的新版本,不斷改進和增強功能,給深度學習帶來了驚人的進步。這也反映在我們的一系列挑選工作中。最早的三次評測【20】表明,Tensorflow完全不能和Torch,Theano和Caffe相提并論。但是僅僅兩個月后,【22】的結(jié)果已經(jīng)顯示Tensorflow追趕上來,到了最后的評測【5】的時候,Tensorflow已經(jīng)處在領(lǐng)先的地位了。我們預測Tensorflow的性能還會繼續(xù)改進,前途無量。特別是在分布式處理的場景下,目前和可以預見的將來,Tensorflow都將是領(lǐng)先地位。

七. Tensorflow的實際應(yīng)用

Tensorflow發(fā)布才短短六個月,學術(shù)界和工業(yè)界還沒有能夠完全擁抱Tensorflow,一些現(xiàn)有應(yīng)用的移植還需要時間,新的研究還需時日。但是一點毋庸置疑,谷歌已經(jīng)積極應(yīng)用和推廣Tensorflow在各種任務(wù)中【19】【25】【26】【27】【28】。我們將選擇性的看一看這些應(yīng)用是怎么使用Tensorflow的。

A. 學術(shù)界

首先提到Tensorflow的是2016年二月的文獻【29】,來自谷歌大腦組的Szegedy,Ioffe和Vanhoucke發(fā)表的文章。他們用Tensorflow改進了Inception模型【19】,主要用于圖像識別。作者給出了ImageNet測試集最高5檔3.08%偏差的好成績。

在文獻【25】,Ramsunder等人對于藥品發(fā)現(xiàn)的多任務(wù)網(wǎng)絡(luò)的討論使用了Tensorflow,這是斯坦福大學和谷歌之間的聯(lián)合研究工作。這篇文章描述了使用Tensorflow構(gòu)建深層神經(jīng)網(wǎng)絡(luò)做虛擬掃描來選擇潛在的候選藥物。這是為了幫助醫(yī)藥公司和科研社區(qū)尋找為治療疾病的新藥。

August和Ni應(yīng)用Tensorflow創(chuàng)建了遞歸神經(jīng)網(wǎng)絡(luò)優(yōu)化動態(tài)解耦,一種在量子內(nèi)存抑制誤差的技術(shù)?!?0】作者旨在維持量子糾纏態(tài),這是構(gòu)建通用量子計算機的關(guān)鍵需求。

最后,文獻【31】研究了自然語言處理的sequence-to-sequence模型,作者使用Tensorflow,采用滑動窗口技術(shù)去做字符級別的英語到拉脫維亞語在音頻和視頻內(nèi)容的翻譯。作者用這個方法去分類電視節(jié)目,廣播節(jié)目,并且聚類單個的故事。

B. 工業(yè)界

除了谷歌之外,工業(yè)界還很少有人使用Tensorflow,至少公開的情況來看是這個樣子。所以我們來看看谷歌的Tensorflow應(yīng)用情況。

最近,谷歌在調(diào)整它的核心業(yè)務(wù)算法PageRank【32】系統(tǒng)RankBrain【33】,使用的技術(shù)就是Tensorflow。RankBrain使用大規(guī)模分布式深度神經(jīng)網(wǎng)絡(luò)來做搜索排序。根據(jù)文獻【33】,超過15%發(fā)給www.google.com的查詢是全新查詢。RankBrain系統(tǒng)可以通過相似性比對來給出未知查詢建議。

另一個應(yīng)用是谷歌的智能郵件回復系統(tǒng)【27】。谷歌已經(jīng)整合了智能回復功能在其郵件系統(tǒng)的Inbox里面。系統(tǒng)使用遞歸神經(jīng)網(wǎng)絡(luò)和特定LSTM模塊進行序列到序列的學習和自然語言理解。一個編碼器映射一個語料庫到一個“思維向量”,而解碼器則在語法和語義上合成正確的回復,然后以建議的形式呈現(xiàn)給用戶。

在文獻【26】,谷歌在使用卷積神經(jīng)網(wǎng)絡(luò)做圖像識別和自動文本翻譯。作為谷歌手機的內(nèi)置功能,對于用戶來說的外文可以被算法識別,然后翻譯成用戶識別語言,并且呈現(xiàn)在原文所在圖像上。這種方法可以用來翻譯圖片里的街道名。文獻【26】特別強調(diào)如果部署這種算法在低端手機設(shè)備和慢速網(wǎng)絡(luò)上。因此,神經(jīng)網(wǎng)絡(luò)訓練小模型,然后應(yīng)用于資源首先的場景也在發(fā)展。

最后,我們已經(jīng)注意到谷歌旗下的DeppMind,著名的AI研究機構(gòu)已經(jīng)把他們的研究平臺從Torch7轉(zhuǎn)移到Tensorflow了?!?8】有消息稱【17】,DeepMind使用Tensorflow,在谷歌新發(fā)布的張量處理單元(TPU)上訓練他們的AlphaGo模型。該文獻作者就是谷歌DeepMind的雇員,揭示了為什么Tensorflow對于DeepMind有好處的四個理由:

1)Tensorflow的大規(guī)模應(yīng)用是構(gòu)建在谷歌云平臺上,可以很容易提供充足的計算力。

2)Tensorflow支持TPU這樣的硬件擴展。

3)Tensorflow的主要編程接口是Python,這是谷歌的核心編程語言,要比Lua能夠得到更好的支持。

4)Tensorflow是能夠很好支持多GPU的框架。

八. 總結(jié)

我們已經(jīng)從各個方面完整的討論了Tensorflow,這種基于計算圖的開源深度學習庫的各種特性,包括能夠快速計算梯度,它固有的支持分布式計算的特性,強有力可視化工具。它能夠在很細顆粒度構(gòu)建神經(jīng)網(wǎng)絡(luò),允許高度定制模型,同時也支持一些快速原型搭建的封裝庫,比如TFLearn。相比Torch,Theano之類的框架,Tensorflow增加了新特征和改進了現(xiàn)有特性。它在性能方面的表現(xiàn),開始不盡人意,但是隨著時間的推移,不斷的隨著新庫的發(fā)布在改進。

我們注意到對于Tensorflow的分布式運行性能的評測目前開展的很少。我們認為這是很重要的一環(huán),也是學術(shù)界需要深入研究的一點。

Tensorflow已經(jīng)在開源社區(qū)取得了相當?shù)娜藲夂蛷娪辛Φ牡谌街С?。谷歌已?jīng)做出了明智的決定。我們相信,Tensorflow不僅僅對于它的所有者有利,也會惠及更為廣大的科研社區(qū);它會打開通往更快更大規(guī)模的人工智能之門。

附錄-1

#!/usr/bin/env python

# -*- coding: utf-8 -*-

''' A one-hidden-layer-MLP MNIST-classifier. '''

from__future__importabsolute_importfrom__future__importdivisionfrom__future__importprint_function

# Import the training data (MNIST)

fromtensorflow.examples.tutorials.mnistimportinput_data

importtensorflow as tf

# Possibly download and extract the MNIST data set.

# Retrieve the labels as one-hot-encoded vectors.mnist = input_data.read_data_sets('/tmp/mnist',

one_hot=True)

# Create a new graph

graph = tf.Graph()

# Set our graph as the one to add nodes to

with graph.as_default():

# Placeholder for input examples (None =

variable dimension)

examples = tf.placeholder(shape=[None, 784],

dtype=tf.float32)

# Placeholder for labels

labels = tf.placeholder(shape=[None, 10],

dtype=tf.float32)

weights =

tf.Variable(tf.truncated_normal(shape=[784,

10], stddev=0.1))

bias = tf.Variable(tf.constant(0.1, shape=[10]))

# Apply an affine transformation to the input

features

logits = tf.matmul(examples, weights) + bias

estimates = tf.nn.softmax(logits)

# Compute the cross-entropy

cross_entropy = -tf.reduce_sum(labels*tf.log(estimates),

reduction_indices=[1])

loss = tf.reduce_mean(cross_entropy)

# Create a gradient-descent optimizer that

minimizes the loss.

# We choose a learning rate of 0.01

optimizer =

tf.train.GradientDescentOptimizer(0.5).minimize(loss)

# Find the indices where the predictions were

correct

correct_predictions = tf.equal(

tf.argmax(estimates, dimension=1),

tf.argmax(labels, dimension=1))

accuracy =

tf.reduce_mean(tf.cast(correct_predictions,

tf.float32))

with tf.Session(graph=graph) as session:

tf.initialize_all_variables().run()forstepinrange(1001):

# And finally the loss

example_batch, label_batch =

mnist.train.next_batch(100)

feed_dict = {examples: example_batch, labels:

label_batch}

ifstep % 100 == 0:

_, loss_value, accuracy_value =

session.run(

[optimizer, loss, accuracy],

feed_dict=feed_dict

)print('Loss at time {0}: {1}'.format(step,

loss_value))print('Accuracy at time {0}:

{1}'.format(step, accuracy_value))

optimizer.run(feed_dict)

參考文獻

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
TensorFlow入門極簡教程(一)
從框架優(yōu)缺點說起,這是一份TensorFlow入門極簡教程
TensorFlow框架
MNIST機器學習入門 中文版
機器學習怎么快速入門?此文教你「宏觀」學習神經(jīng)網(wǎng)絡(luò)和TensorFlow(實例教程)
TensorFlow是什么?怎么用?終于有人講明白了
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服