卷積神經網絡CNN(二)池化、結構、誤差反向傳播

上一篇介紹了CNN基本概念和卷積的知識,CNN的特徵抽取除了包含卷積,還包含池化。

池化

池化又叫子採樣,是特殊的卷積。池化比較好理解,還是上篇公司工作交接的例子,每個銷售區域有100個老員工,我們可以先推舉一個最懂本區域的業務人員參與交接(如各區域的領導),其他人員不必參與交接;或者每個區域內部先開一個會,把100個老員工的經驗結合在一起,生成一個會議紀要,根據這份紀要與新員工交接。這實際對應兩種池化方式,前一種是最大化池化,後一種是平均池化。

放到圖像識別的例子裏,池化是爲了降維。例如一個250*250像素的圖像,從上到下、從左到右用2*2大小的矩陣掃描,也就是說250*250的圖像中每個連在一起2*2的小圖像,都用這四個點中像素值最大的點代替,其他像素點捨棄;或者用這四個像素值的均值代替,也就完成了池化。注意平均池化實際相當於卷積核元素都是1的矩陣。


以上圖爲例,池化以後圖像會變模糊,高、寬變爲原來的一半。

結構

之所以沒在本篇開頭說結構,是因爲希望大家一開始有個感性的認識,知道卷積是爲了做什麼,池化是爲了做什麼,否則一開始看結構會不知所云,不便於理解。

在瞭解卷積、池化以後,CNN的結構就比較簡單了,首先它依然有輸入層和輸出層,輸入層是一個矩陣,接收圖像的二維矩陣信息(此處圖像只考慮一個通道),經過卷積、池化、卷積、池化……得到的依然是矩陣。但是輸出層與BPNN一樣,並非一個矩陣,而是一個向量,例如(1, 0, 0)代表圖像是狗,(0, 1, 0)代表圖像是貓, (0, 0, 1)代表圖像是鳥,(0.9, 0.1, 0)代表圖像很大概率是狗,小概率是貓,所以CNN在最後的結構需要把矩陣展開,然後類似BPNN那樣全連接神經網絡,輸出到一個一維向量中。

誤差反向傳播

首先了解前向傳播。前向傳播的過程是,圖像的原始像素值輸入到CNN中,經過卷積操作,得到特徵平面,特徵平面經過激活函數激活,輸出到池化層,池化層經過簡單的最大值池化或均值池化,再輸出給下一層卷積,經過N次這樣反覆處理,即可完成從識別簡單的輪廓、線到識別抽象物體的飛躍。以上過程存續的結果都是二維的矩陣。最後連接到一個全連接層,輸出成一個一維向量。最後經過激活函數即可得到圖像屬於每個類的概率。

卷積層的激活函數可以選擇ReLU函數(線性整流函數),池化層沒有激活函數,池化的結果直接傳遞給下一層,輸出層的激活函數可以選擇Softmax,Softmax是專門處理多分類的激活函數,可以輸出樣本分別屬於各個類的概率。

ReLU函數見下圖


ReLU函數有一定生物學道理,即信號到達一定閾值以後才激活

Softmax函數見下式


其中Z是一個k維向量,各個分量用e做指數,佔指數之和的比例,即爲Z屬於該類的概率。

需要訓練的參數是卷積核矩陣中的值以及偏置。訓練好的卷積核矩陣理論上可以表示物體的相關特徵(如針對汽車的輪胎形狀)。

誤差反向傳播與BPNN不太一樣,因爲涉及到卷積、池化的操作,稍微有些複雜。從後往前分析,全連接層的反向傳播不太複雜,只需要把softmax或其他激活函數形式寫出來求導即可。比較關鍵的是卷積層、池化層的反向傳播。

(1)池化層向上傳播

假設CNN的結構是卷積層A(L-1層)激活-本池化層(L層)-卷積層B,即本池化層上一層是卷積層A,下一層是卷積層B。還記得BPNN裏的δ嗎,很多神經網絡都用了這個結果。δ表示誤差傳播到節點的結果,這裏想給大家灌輸一個思想,δ具體來看是損失函數對這個節點激活前的導數。

已經知道誤差傳播到本池化層的結果是(即誤差對本池化層激活前的導數),現在求誤差傳播到卷積層A的結果

正向傳播的時候,從卷積層A到池化層分別作了激活、池化操作,所以誤差反向傳播的時候要先求池化的導數,再求激活函數的導數。

池化使得結果降維(如文章開頭250*250降維成125*125),所以爲了將誤差還原回去,需要從降維後的小矩陣125*125還原回降維前的大矩陣250*250。

如果是最大值池化,那麼將誤差指定給小範圍矩陣像素最大值的點;如果是平均值池化,那麼將誤差平均分給小範圍矩陣的各個點即可。我們把這個過程叫做upsample,顧名思義,這裏的操作是將維度擴大,將誤差以一定規則分給小範圍的各個點。還是公司工作交接的例子,假如某個銷售區域交接工作出了差錯,如果是最大化池化,由於是領導在進行工作交接,那麼讓領導背鍋;如果是平均池化,由於大家都參與了開會並形成會議紀要,那麼所有區域員工都揹負相同的責任。


因此


其中a表示激活後的值(activation), z表示激活前的值。

上式最右側兩項分別表示對池化求導和對ReLU等激活函數求導。

(2)卷積層向上傳播

假設CNN的結構是池化層A(l-1層)-本卷積層(l層)-池化層B,即本卷積層向上把誤差傳播到池化層A。已經知道誤差傳播到本卷積層的結果是(即誤差對本卷積層激活前的導數),現在求誤差傳播到池化層A的結果

正向傳播的時候,由於池化層沒有激活(池化後的樣子就是傳到下一層的樣子),所以從池化層A到卷積層只有卷積的操作,所以誤差反向傳播就是求卷積的導數。

卷積的導數稍微有些特別,因爲卷積操作本身比較特別。


這裏的*表示卷積,rot180表示將矩陣旋轉180度,即上下各翻轉一次。

下面用一個例子說明,爲了簡化假設這裏偏置都爲0。

卷積操作如下圖所示


現在z傳過來的誤差是

例如,對於a11來說,它只參與了z11的運算,J代表損失函數。


對於a12來說,它參與了z11和z12的運算


同理,可以得到

以上可以表示成


其中*表示卷積

δ推導到各個卷積核具體權重和每層偏置就十分簡單了,與BPNN道理一樣,這裏不再詳述。



總結

爲了處理圖像問題,BPNN的算法不易求解,而且不符合仿生學的特點。CNN是專門爲了處理圖像等矩陣形成的神經網絡,後一層神經元只與前一層部分區域神經元相連,大大減小參數;相連的權重是公用的,更進一步減小參數;池化層對圖像降維,繼續減小了參數。是在滿足仿生的基礎上不斷減小參數,使得CNN可以訓練。

延續BPNN的思想,CNN誤差向後傳導重點是求δ,δ是誤差傳播到節點的值,具體地說,是損失函數對節點輸入值(未激活前的值)的導數。求出δ再求誤差對權重、偏置的導數就十分容易了。由於卷積與池化交替進行,所以“卷積向上傳導到池化”和“池化向上傳導到卷積”情況不同。池化的操作求導比較容易理解,卷積的操作求導稍微有些複雜,需要對矩陣旋轉操作。我們用一個例子證明了算式的正確性。

參考資料

1. http://www.cnblogs.com/pinard/p/6489633.html

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