天天看點

深度學習入門:幾幅手稿講解CNN

本文來自AI新媒體量子位(QbitAI)

學習深度神經網絡方面的算法已經有一段時間了,對目前比較經典的模型也有了一些了解。這種曾經一度低迷的方法現在已經吸引了很多領域的目光,在幾年前僅僅存在于研究者想象中的應用,近幾年也相繼被深度學習方法實作了。

無論是對資料的分析或是生成,無論資料形式是圖像、視訊、音頻、文本還是其它複雜次元,也無論是下棋、玩遊戲還是無人駕駛汽車導航,似乎總有人會發掘出這種強大工具的新用途。人類剛剛将仿生學運用到“如何創造智能”這個問題上,就發現了光明的前景。

我把在組裡介紹深度學習(Deep Learning)基礎知識時畫的幾幅手稿分享出來,希望能幫助新人更快的了解這種方法。我在講解的過程中參考了李宏毅老師的PPT),推薦讀者結合起來閱讀。

深度學習入門:幾幅手稿講解CNN

任何一個算法都可以看作一個函數。輸入x經過函數f産生輸出y,我們期望獲得的輸出是,是以我們的目的是找到一個函數f,使得y與盡可能的接近。

同時,函數y與W由一組參數确定,是以輸出y可以看作是輸入x和參數W的因變量。當參數W固定時,每當輸入不同的x,其對應的輸出y一般也會不同。這時,y與之間的差異稱作誤差(loss)。

描述x,W,與誤差loss之間關系的函數叫作誤差函數(loss function)。對于實際問題,一般誤差函數總會存在一個最小值。尋找最優函數f的過程,實際上就是尋找一組參數W,使得無論輸入x如何(當然是位于定義域内的x),其誤差總是最小的。

對于分類問題,函數f就是分類器,W就是需要通過訓練獲得的分類器參數。

深度學習入門:幾幅手稿講解CNN

在神經網絡算法中,最基本的組成機關如圖中左上所示,前一層神經元

深度學習入門:幾幅手稿講解CNN

深度學習入門:幾幅手稿講解CNN
深度學習入門:幾幅手稿講解CNN

(有時還有一個按層獨立的疊加項b,稱為偏置節點bias),經過權邊

深度學習入門:幾幅手稿講解CNN
深度學習入門:幾幅手稿講解CNN
深度學習入門:幾幅手稿講解CNN

連接配接到下一層的節點z。

權重w與節點a之間可以是簡單的相乘再求和(線性網絡),也可以是卷積後再求和(卷積神經網絡,Convolutional Neural Networks,CNN),或者是其他的計算形式。

即便是簡單的線性運算,一個基本的單元可以用來表示一個線性分類器(左下),也可以用于線性拟合(右下),而且經過多層的累積計算之後還可以處理更複雜的問題。

深度學習入門:幾幅手稿講解CNN

卷積神經網絡當中的“卷積”(convolution)與圖像進行中的濾波器(filter)十分相似,隻不過在濾波器中求和時輸入元素與視窗元素是同向的,而在卷積計算中輸入元素與視窗元素是反向的(注意公式中w的下标)。

是以,一些依賴第三方庫(比如OpenCV)的實作會直接把二維的卷積核做水準和豎直兩個方向的翻轉(或者旋轉180度)之後直接調用一個濾波器函數(filter2D)就完成了卷積的計算。

在特征提取方面,卷積運算的作用與濾波器相同。如圖中下方所示,假設在數軸上的輸入資料是經過{2,-1,1}的一條曲線,與一個{1,-2,1}的核進行濾波(或者經過水準翻轉後進行卷積),會得到一個比較大的輸出(5),經過激活函數(actiation function)會産生一個十分接近于1的激活輸出。這時,我們可以說輸入a符合特征w的模式(pattern)。

深度學習入門:幾幅手稿講解CNN

計算機科學中的神經網絡算法隻是從仿生學上部分借鑒了人類大腦的結構。上面的截圖來自CrashCourse的科普視訊。在大腦的神經元(Neuron)中,輸入信号經過樹突(dendrite)傳入,然後再從軸突(Axon)傳遞出去。

在神經元内部,資訊以電信号方式傳遞,在神經元之間則以化學信号傳遞。在傳遞的過程中,信号的強度和速度是一定的,但頻率是可變的。

是以信号的強弱(比如痛感、情緒等)是以信号頻率的高低來區分的。另外神經元之間的連接配接是多對多的,即一個神經元可以有多個輸入和輸出。

與之相比,神經網絡算法一般沒有信号頻率的概念,即每個節點隻向外産生一次激活(RNN遞歸計算的節點可以看作展開成一條節點鍊,但是鍊上每個節點依然隻經過一次計算)。而且,目前的算法大多是嚴格按層級進行計算,并不像生物體神經元那樣在三維空間中呈現紛繁複雜的結構。

深度學習入門:幾幅手稿講解CNN

在神經網絡中,層與層之間的連接配接分為全連通(fully-connected)與局部連通(local connected)兩種。一些比較古老的文獻認為局部連通的計算形式可以用卷積的形式來表示,是以錯誤地把這種經過簡化計算的局部連通網絡稱為卷積網絡。

局部連通與全連通相比,參數數量要少得多,是以在過去計算機性能不佳時是一個比較有效的性能優化有段。但與此同時,局部連通也不可避免地引入了隻有相鄰節點(

深度學習入門:幾幅手稿講解CNN
深度學習入門:幾幅手稿講解CNN
深度學習入門:幾幅手稿講解CNN

)的輸出才與下層節點(

深度學習入門:幾幅手稿講解CNN

)有關的限制,對大多實際問題是不合理的。

直到Dropout的出現,結合了二者的優點,同時還提高了網絡的泛化能力,成為目前十分流行的技術。

深度學習入門:幾幅手稿講解CNN

對于一個機器學習算法來說(也可以推廣到其他領域的算法),最關鍵的三點是模型、資料和誤差函數。

模型即确定輸入、參數與輸出之間的關系;資料即我設計的模型是針對什麼樣的資料,期望得到什麼樣的輸出;誤差函數是評價一個算法好壞的關鍵,需要用明确的表達式合理地衡量實際輸出與理想輸出之間的差異。

前文說過,尋找一個最優函數f的過程,即尋找一個使誤差e最小的參數W的過程。如果我們規定的誤差e是可微的,那麼最優參數

深度學習入門:幾幅手稿講解CNN

必然落在誤差函數的駐點處(e對W的偏導等于0)。但是稍微複雜一點的問題都無法一下子确定最優參數

深度學習入門:幾幅手稿講解CNN

,我們隻能從一個猜測的

深度學習入門:幾幅手稿講解CNN

出發來尋找最優值。這就很自然地引入了梯度下降法(Gradient Descent)。

對于一個可微函數(誤差函數),其上任意一點處的偏導大小代表該點處切線斜率大小,方向(正負号)代表這條切線是向上還是向下的。因為我們需要在變量W的方向上尋找最低點,是以要向梯度方向的反方向(即下降方向)進行搜尋。

需要注意在一些問題中,誤差越大并不代表錯誤得越離譜,而是為了對模型的糾正過程中施加一個更大的作用力。

網絡上有很多關于梯度下降法的介紹,這裡不再贅述。推薦閱讀An overview of gradient descent optimization algorithms來了解一些常用的梯度方法。

推薦文章連結:

http://ruder.io/optimizing-gradient-descent/

深度學習入門:幾幅手稿講解CNN

這張圖來自李宏毅老師的PPT,是為了說明可能會造成訓練收斂緩慢的原因。在函數平緩的區域,由于偏導本身數值很小,會導緻參數的更新量也很小,這時就需要比較大的步長。

在鞍點時,某一軸上是極小點,但在其他軸上并不是極小點,但由于誤差函數形式的原因(比如涉及到對誤差取偶數次幂),會表現為在鞍點周圍誤差都大于鞍點,是以使得訓練過程誤“收斂”于鞍點。由于大量的局部極小點和鞍點的存在,深度神經網絡訓練的調參也是一個十分精細的工作。

關于在鞍點方面的分析,請參考Identifying and attacking the saddle point problem in high-dimensional non-convex optimization。

論文連結:

https://arxiv.org/abs/1406.2572

深度學習入門:幾幅手稿講解CNN

深度神經網絡一般用反向傳播訓練方法(Back Propagation)來疊代地更新參數。上圖是以線性網絡為例解釋BP的計算過程,公式應該可以自明,我就不用文字贅述了。

對于卷積網絡,其實計算過程是相同的,隻不過把偏導項之間的乘法替換為卷積(卷積核在水準和豎直翻轉之後的卷積)。推薦閱讀Backpropagation in Convolutional Neural Network了解CNN中BP算法的細節。

深度學習入門:幾幅手稿講解CNN

當訓練結果不好時,可能會有兩種結果,欠拟合與過拟合。欠拟合是指模型不足以對訓練集産生比較高的分類精度,從誤差-疊代曲線上表現為無論是訓練期間還是測試期間,誤差都比較高。

這說明模型對特征的提取不夠,不足以用來描述樣本間的差異。這時一般需要優化方法來解決這個問題,比如改變激活函數、誤差函數,或者換一種梯度下降方法(以及調整梯度方法的參數)。

過拟合是指模型對訓練集有比較高的分類精度,但對測試集表現不佳,從誤差-疊代曲線上表現為在訓練期間誤差能夠收斂到一個較小值,但測試期間誤差卻比較大。

這說明模型過分地依賴訓練樣本的特征,對沒有遇見過新樣本不知所措,缺乏泛化能力。這時需要正則化方法來提高模型對一般性樣本的适應性,比如Dropout和Batch Normalization。

誤差不收斂的一個更常見的原因——尤其是在一個新模型剛剛建立時——是梯度消失或梯度爆炸。

在網絡中缺少比較可靠的正則化技術時,在網絡不斷疊代訓練的過程中(甚至第二次疊代開始)會發現新樣本産生的誤差梯度在反向傳播的過程中越來越小(或越來越大),有時呈現每一兩層就減小(或增大)一個數量級。

梯度趨向消失時,無論訓練多久,會發現最淺層(前一兩層)的參數與初始值并沒有太大變化,這就使得淺層的存在失去了意義,而且這也會使訓練過程變得非常緩慢。梯度爆炸時,僅僅幾次疊代之後就會發現某一層所有節點的輸出都變成了1(或者十分接近于1),這時網絡也就失去了分類的能力。

深度學習入門:幾幅手稿講解CNN

既然已經知道網絡的輸入和參數會影響最終輸出的誤差,那麼也就可以假設我們可以在一個三維坐标上畫出三者的關系。如圖中所示,當參數(parameter)固定時,每輸入不同的樣本(sample),就會産生不同的誤差(loss),因為真實樣本x與理想樣本

深度學習入門:幾幅手稿講解CNN

相比總是存在誤差的。

而對于同一個樣本,變化的參數一般也會産生變化的誤差。是以訓練網絡的過程實際上是在sample和parameter兩個軸上不斷變化時找到loss的最低點。

在訓練模型時,一般會将訓練集等分為若幹小集合(mini-batch),一次将一個mini-batch輸入網絡,計算完所有mini-batch後——如果覺得網絡精度還達不到要求——将所有樣本随機排序,再分割為若幹mini-batch進行訓練。

這個過程可以看作在sample軸上随機跳躍,在parameter軸上逐漸前進地搜尋,能夠盡可能地保證搜尋到的最低點是所有樣本的最低點。

深度學習入門:幾幅手稿講解CNN

特征提取是一個分類器的核心,深度學習的優勢就在于它能自動從原始資料提煉出特征,并以層級的邏輯組合這些特征來描述原始樣本。我在最後一幅圖中用一個簡單的例子來說明CNN的層級結構是如何解決圖像分類問題的。

假設我們需要用機器視覺方法對圖A(兩個三角形構成松樹的形狀)和圖B(兩個三角形構成鑽石的形狀)進行區分。

在神經網絡方法出現之前,一種比較可行的方法是通過圖像進行中的直線檢測方法找到圖像中所有直線,然後通過直線參數之間的關系來确定如下判斷規則:如果下面的三角形尖角朝上,即為松樹;如果尖角朝下,即為鑽石。

經過細緻的調參,這個算法應該已經可以完美解決區分圖A與圖B的問題了。如果現在又來了一副圖C(也許是兩個三角形水準排列構成小山的形狀,也可能根本不包含三角形),需要用之前的算法來同時區分這三幅圖檔,怎麼辦?

好在我們可以用CNN來解決這個問題。

首先需要注意,我在這一小節所指“卷積”實際上是濾波操作,因為卷積涉及翻轉,不利用直覺了解。

假設我們訓練好的網絡有兩層隐層,第一層包含兩個節點(圖中第二列藍色圖形,分别為一條左斜線與一條右斜線),第二層包含四個節點(圖中第四列藍色圖形,分别為一條水準線,一條豎直線,一條左斜線與一條右斜線)。

圖A經過第一隐層,得到圖中第三列黑色的圖形。黑色的圓點代表原始圖像中對某個卷積核激活值高的區域,白色代表激活值低的區域。圖A松樹左側的兩條斜邊經過“左斜線”卷積核計算得到位于圖像左側的兩個黑色圓點,其他區域都不符合“左斜線”這個特征,是以輸出值全部忽略為0。

同時,隻有松樹右側的兩條斜邊會對“右斜線”卷積核産生高激活(得到兩個位于右側的黑色圓點),其他區域産生的激活都為0。

同理,圖B鑽石圖像經過“左斜線”與“右斜線”卷積核産生兩幅不同的圖像(一副在左上和右下有黑點,一副在右上和左下有黑點)。這時,第一層的計算就完成了。

與一般的CNN模型一樣,我們把第一層的結果(圖中第三列)輸入第二隐層之前要縮小一下圖像的尺度。經過縮小之後(你可以眯起眼睛離螢幕稍遠些觀察),第三列的四個圖形分别變成了一條在左側的豎線,一條在右側的豎線,一條右斜線和一條左斜線。

現在,我們拿第二層的四個卷積核(第四列藍色圖形)來對這四個結果進行卷積再求和。

為了簡化,如果在圖像中存在一個區域使其與某卷積核的激活輸出值較高,就将該卷積核的對應輸出記為1;如果不存在這樣的一個區域即記為0。

這樣,圖中第三列第一個圖像對四個卷積核分别産生(0,第二個圖像産生(0,是以圖A的最終結果是這兩個向量的和,為(0。而圖B的結果為(0。

雖然圖A與圖B有相似之處,但經過兩次卷積得到的向量是完全不同的,通過這兩個向量,我們就能唯一地确定圖A與圖B。

如果有新的樣本加入,我們隻需要改變一下圖例中的卷積核數目和形狀(或者甚至不對網絡做任何修改)也能夠輕松地實作分類。當然,CNN方法在實際運用時是不需要人為地設計卷積核的,而是依靠對樣本的訓練逐漸構造的。

其實,作為一個尚未成熟的工具,深度學習的優點與缺點同樣明顯。其優點毋庸置疑,是推動其在各領域蔓延的高分類精度,确切地說是它能夠自主歸納特征,免去了過去慢慢手工篩選特征來提高精度的過程。

深度學習方法的缺點也十分緻命,即訓練結果完全的不可預測性。在訓練完成、進行測試之前,即便是有經驗的工程師也難以給出其精度的界,更無法預知訓練後的參數會變成什麼樣。

雖然這種說法對于一個機器學習方法來說有些苛刻,畢竟在數值計算領域有很多疊代算法也會因為微小的參數變化而難以收斂。但是作為一個參數量級驚人的算法,人類對其參數含義的解讀也是困難的。其在多個領域的廣泛運用産生的一個結果是,參數的不可預測性會帶來其行為的不可預測性。

雖然技術的推廣者經常會如何保證甚至如何吹噓他們訓練出來的模型在很多條件下都有很高的精度(或者說,執行設計者所期望的行為),但更有可能的是,吹牛的人并不知道模型究竟為什麼會在特定條件下産生特定的結果。

作為一個“黑盒”算法,其對外的表征是高分通過所有測試,但對于測試内容沒有考慮到的情況才是值得擔心的。一個廉價而高效的工具在市場上的阻力是比較小的,那麼比市場上現有算法更複雜更強大的算法勢必會被不斷推出。

如果我們能夠假定“智能”隻是一個不斷收集和處理資料的過程,那麼我們也可以說《終結者》所描述的世界也并純粹的想象了。

感謝嶽翰的分享~

本文作者:嶽翰

原文釋出時間:2017-08-19

繼續閱讀