揭祕TensorFlow:Google開源到底開的是什麼?

【編者按】本文作者李理 ,人工智能科技公司出門問問NLP工程師。

揭祕TensorFlow:Google開源到底開的是什麼?

這兩天發現朋友圈被Google開源深度學習系統TensorFlow的新聞刷屏了。這當然是一個很好的消息,尤其對我們這種用機器學習來解決實際問題的工程師來說更是如此。但同時很多人並不清楚聽起來神乎其神的“TensorFlow”到底是什麼,有什麼意義。

我是人工智能科技公司“出門問問”的工程師,對人工智能“深度學習”理論有一定的瞭解,在這裏就爲大家“破霧”,聊一聊Google的開源系統TensorFlow。

什麼是深度學習?

在機器學習流行之前,都是基於規則的系統,因此做語音的需要了解語音學,做NLP的需要很多語言學知識,做深藍需要很多國際象棋大師。

而到後來統計方法成爲主流之後,領域知識就不再那麼重要,但是我們還是需要一些領域知識或者經驗來提取合適的feature(特徵),feature的好壞往往決定了機器學習算法的成敗。對於NLP來說,feature還相對比較好提取,因爲語言本身就是高度的抽象;而對於Speech或者Image來說,我們人類自己也很難描述我們是怎麼提取feature的。比如我們識別一隻貓,我們隱隱約約覺得貓有兩個眼睛一個鼻子有個長尾巴,而且它們之間有一定的空間約束關係,比如兩隻眼睛到鼻子的距離可能差不多。但怎麼用像素來定義”眼睛“呢?如果仔細想一下就會發現很難。當然我們有很多特徵提取的方法,比如提取邊緣輪廓等等。

但是人類學習似乎不需要這麼複雜,我們只要給幾張貓的照片給人看,他就能學習到什麼是貓。人似乎能自動“學習”出feature來,你給他看了幾張貓的照片,然後問貓有什麼特徵,他可能會隱隱預約地告訴你貓有什麼特徵,甚至是貓特有的特徵,這些特徵豹子或者老虎沒有。

深度學習爲什麼最近這麼火,其中一個重要的原因就是不需要(太多)提取feature。

從機器學習的使用者來說,我們以前做的大部分事情是feature engineering,然後調一些參數,一般是爲了防止過擬合。而有了深度學習之後,如果我們不需要實現一個CNN或者LSTM,那麼我們似乎什麼也不用幹。(機器讓工人失業,機器學習讓搞機器學習的人失業!人工智能最終的目的是讓人類失業?)

揭祕TensorFlow:Google開源到底開的是什麼?

但是深度學習也不是萬能的,至少現在的一個問題是它需要更強的計算能力才能訓練出一個比較好的模型。它還不能像人類那樣通過很少的訓練樣本就能學習很好的效果。

其實神經網絡提出好幾十年了,爲什麼最近才火呢?其中一個原因就是之前它的效果並不比非深度學習算法好,比如SVM。

到了2006年之後,隨着計算能力的增強(尤其是GPU的出現),深度神經網絡在很多傳統的機器學習數據集上體現出優勢來之後,後來用到Image和Speech,因爲它自動學出的feature不需要人工提取feature,效果提升更加明顯。這是否也說明,我們之前提取的圖像feature都不夠好,或者是根據人腦的經驗提取的feature不適合機器的模型?

很多人對深度學習頗有微詞的一個理由就是它沒有太多理論依據,更多的像蠻力的搜索——非常深的層數,幾千萬甚至上億參數,然後調整參數擬合輸入與輸出。其實目前所有的機器學習都是這樣,人類的大腦的學習有所不同嗎,不是神經元連接的調整嗎?

但不管怎麼說,從深度神經網絡的使用者(我們這樣的工程師)的角度來說,如果我們選定了一種網絡結構,比如CNN,那麼我們要做的就是根據經驗,選擇合適的層數,每層的神經元數量,激活函數,損失函數,正則化的參數,然後使用validation數據來判定這次訓練的效果。從效果來說,一般層次越多效果越好(至少相對一兩層的網絡來說),但是層次越多參數也越多,訓練就越慢。單機訓練一個網絡花幾天甚至幾周的時間非常常見。因此用多個節點的計算機集羣來訓練就是深度學習的核心競爭力——尤其對於用戶數據瞬息萬變的互聯網應用來說更是如此。

常見深度神經網絡的訓練和問題

對於機器學習來說,訓練是最關鍵也最困難的部分,一般的機器學習模型都是參數化的模型,我們可以把它看成一個函數y=f(w;x)。

比如拿識別圖像來說,輸入x是這張圖片的每個像素值,比如MNIST的數據是28*28的圖片,每個點是RGB的顏色值,那麼x就是一個28*28*3的向量。而一個模型有很多參數,用w表示。輸出y是一個向量,比如MNIST的數據是0-9的10個數字,所以我們可以讓y輸出一個10維的向量,分別代表識別成0-9的置信度(概率),選擇最大的那個作爲我們的識別結果(當然更常見的是最後一層是softmax而不是普通的激活函數,這樣這個10維向量加起來等於1,可以認爲是分類的概率)。

而訓練就是給這個模型很多(x,y),然後訓練的過程就是不斷的調整參數w,然後使得分類錯誤儘可能少(由於分類錯誤相對w不連續因而不可求導,所以一般使用一個連續的Loss Function)。

對於神經網絡來說,標準的訓練算法就是反向傳播算法(BackPropagation)。從數學上來說就是使用(隨機)梯度下降算法,求Loss Function對每個參數的梯度。另外我們也可以從另外一個角度來看反向傳播算法,比如最後一層的神經網絡參數,直接造成錯誤(Loss);而倒數第二層的神經網絡參數,通過這一次的激活函數影響最後一層,然後間接影響最終的輸出。反向傳播算法也可以看成錯誤不斷往前傳播的過程。

由於深度神經網絡的參數非常多,比如GoogleNet, 2014年ILSVRC挑戰賽冠軍,將Top5 的錯誤率降低到6.67%,它是一個22層的CNN,有5百多萬個參數。所以需要強大的計算資源來訓練這麼深的神經網絡。

其中,CNN是Image領域常見的一種深度神經網絡。由Yann LeCun提出,通過卷積來發現位置無關的feature,而且這些feature的參數是相同的,從而與全連接的神經網絡相比大大減少了參數的數量。

揭祕TensorFlow:Google開源到底開的是什麼?

(cnn深度神經網絡)

最開始的改進是使用GPU來加速訓練,GPU可以看成一種SIMT的架構,和SIMD有些類似,但是執行相同指令的warp裏的32個core可以有不同的代碼路徑。對於反向傳播算法來說,基本計算就是矩陣向量乘法,對一個向量應用激活函數這樣的向量化指令,而不像在傳統的代碼裏會有很多if-else這樣的邏輯判斷,所以使用GPU加速非常有用。

但即使這樣,單機的計算能力還是相對有限的。

深度學習開源工具

從數學上來講,深度神經網絡其實不復雜,我們定義不同的網絡結構,比如層次之間怎麼連接,每層有多少神經元,每層的激活函數是什麼。前向算法非常簡單,根據網絡的定義計算就好了。

而反向傳播算法就比較複雜了,所以現在有很多深度學習的開源框架來幫助我們把深度學習用到實際的系統中。

我們可以從以下幾個不同的角度來分類這些開源的深度學習框架。

  • 通用vs專用

深度學習抽象到最後都是一個數學模型,相對於傳統的機器學習方法來說少了很多特徵抽取的工作,但是要把它用到實際的系統中還有很多事情要做。而且對於很多系統來說,深度學習只是其中的一個模塊。

拿語音識別來說,語音識別包含很多模塊,比如聲學模型和語言模型,現在的聲學模型可以用LSTMs(一種RNN,也是一種深度學習網絡)來做,但是我們需要把它融入整個系統,這就有很多工作需要做。而且目前大部分的機器學習方法包括深度學習,都必須假設訓練數據和測試數據是相同(或者類似)的分佈的。所以在實際的應用中,我們需要做很多數據相關的預處理工作。


比如Kaldi,它是一個語音識別的工具,實現了語音識別的所有模塊,也包括一些語音識別常用的深度神經網絡模型,比如DNN和LSTM。

而Caffe更多的是用在圖像識別,它實現了CNN,因爲這個模型在圖像識別上效果非常好。

  • 框架vs庫

大部分開源的深度學習工具把整個模型都封裝好了,我們只需要指定一些參數就行了。比如我們使用Caffe的CNN。


但是還有一些工具只是提供一些基礎庫,比如Theano,它提供了自動求梯度的工具。

我們可以自己定義網絡的結構,我們不需要自己求梯度。使用Theano的好處是如果我們“創造”一個新的網絡結構或者是很新的深度神經網絡,那麼其它框架很可能還沒有實現,所以Theano在學術界很流行。當然壞處就是因爲它不可能針對特定的模型做優化,所以可能性能不如特定的實現那麼好。

  • 單機vs集羣

目前大部分的開源工具都是單機版的,有些支持在一個節點的多個GPU訓練,但是支持GPU cluster比較少,目前支持多機訓練的有GraphLab和Deeplearning4j。

Tensor Flow到底是什麼?

Tensor(張量)意味着N維數組,Flow(流)意味着基於數據流圖的計算,TensorFlow即爲張量從圖的一端流動到另一端。

TensorFlow 表達了高層次的機器學習計算,大幅簡化了第一代系統,並且具備更好的靈活性和可延展性。TensorFlow一大亮點是支持異構設備分佈式計算,它能夠在各個平臺上自動運行模型,從電話、單個CPU / GPU到成百上千GPU卡組成的分佈式系統。

揭祕TensorFlow:Google開源到底開的是什麼?

從目前的文檔看,TensorFlow支持CNN、RNN和LSTM算法,這都是目前在Image,Speech和NLP最流行的深度神經網絡模型。

而且從Jeff Dean的論文來看,它肯定是支持集羣上的訓練的。

在論文裏的例子來看,這個架構有點像Spark或者Dryad等圖計算模型。就像寫Map-reduce代碼一樣,我們從高層的角度來定義我們的業務邏輯,然後這個架構幫我們調度和分配計算資源(甚至容錯,比如某個計算節點掛了或者太慢)。目前開源的實現分佈式Deep learning的GraphLab就是GAS的架構,我們必須按照它的抽象來編寫Deep Learing代碼(或者其它分佈式代碼,如果PageRank),而Deeplearning4j直接使用了Spark。

Map-Reduce的思想非常簡單,但是要寫出一個穩定可用的工業級產品來就不容易了。而支持分佈式機器學習尤其是深度學習的產品就更難了,Google的TensorFlow應該是一種抽象方式,可惜現在開源的部分並沒有這些內容。有點像Google開源了一個單機版的Hadoop,可以用這種抽象(Map-reduce)來簡化大數據編程,但是實際應用肯定就大大受限制了。

深度學習能解決所有問題嗎?

至少目前來看,深度學習只是在Speech和Image這種比較“淺層”的智能問題上效果是比較明顯的,而對於語言理解和推理這些問題效果就不那麼好了,也許未來的深度神經網絡能解決更“智能”的問題,但只是目前還不行。

Google開源TensorFlow的意義

這一次的Google開源深度學習系統TensorFlow在很多地方可以應用,如語音識別,自然語言理解,計算機視覺,廣告等等。但是,基於以上論點,我們也不能過分誇大TensorFlow這種通用深度學習框架在一個工業界機器學習系統裏的作用。在一個完整的工業界語音識別系統裏, 除了深度學習算法外,還有很多工作是專業領域相關的算法,以及海量數據收集和工程系統架構的搭建。

不過總的來說,這次谷歌的開源很有意義,尤其是對於中國的很多創業公司來說,他們大都沒有能力理解並開發一個與國際同步的深度學習系統,所以TensorFlow會大大降低深度學習在各個行業中的應用難度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章