和全連接神經網絡相比,卷積神經網絡的訓練要複雜一些。但訓練的原理是一樣的:利用鏈式求導計算損失函數對每個權重的偏導數(梯度),然後根據梯度下降公式更新權重。訓練算法依然是反向傳播算法。
我們先回憶一下上一篇文章零基礎入門深度學習(3) - 神經網絡和反向傳播算法介紹的反向傳播算法,整個算法分爲三個步驟:
最後,根據梯度下降法則更新每個權重即可。
對於卷積神經網絡,由於涉及到局部連接、下采樣的等操作,影響到了第二步誤差項的具體計算方法,而權值共享影響了第三步權重的梯度的計算方法。接下來,我們分別介紹卷積層和Pooling層的訓練算法。
對於卷積層,我們先來看看上面的第二步,即如何將誤差項傳遞到上一層;然後再來看看第三步,即如何計算filter每個權值的梯度。
我們先來考慮步長爲1、輸入的深度爲1、filter個數爲1的最簡單的情況。
假設輸入的大小爲3*3,filter大小爲2*2,按步長爲1卷積,我們將得到2*2的feature map。如下圖所示:
在上圖中,爲了描述方便,我們爲每個元素都進行了編號。用表示第層第行第列的誤差項;用表示filter第行第列權重,用表示filter的偏置項;用表示第層第行第列神經元的輸出;用表示第行神經元的加權輸入;用表示第層第行第列的誤差項;用表示第層的**函數。它們之間的關係如下:
上式中,、、都是數組,是由組成的數組,表示卷積操作。
在這裏,我們假設第中的每個值都已經算好,我們要做的是計算第層每個神經元的誤差項。
根據鏈式求導法則:
我們先求第一項。我們先來看幾個特例,然後從中總結出一般性的規律。
例1,計算,僅與的計算有關:
因此:
例2,計算,與和的計算都有關:
因此:
例3,計算,與、、和的計算都有關:
因此:
從上面三個例子,我們發揮一下想象力,不難發現,計算,相當於把第層的sensitive map周圍補一圈0,在與180度翻轉後的filter進行cross-correlation,就能得到想要結果,如下圖所示:
因爲卷積相當於將filter旋轉180度的cross-correlation,因此上圖的計算可以用卷積公式完美的表達:
上式中的表示第層的filter的權重數組。也可以把上式的卷積展開,寫成求和的形式:
現在,我們再求第二項。因爲
所以這一項極其簡單,僅求**函數的導數就行了。
將第一項和第二項組合起來,我們得到最終的公式:
也可以將式7寫成卷積的形式:
其中,符號表示element-wise product,即將矩陣中每個對應元素相乘。注意式8中的、、都是矩陣。
以上就是步長爲1、輸入的深度爲1、filter個數爲1的最簡單的情況,卷積層誤差項傳遞的算法。下面我們來推導一下步長爲S的情況。
我們先來看看步長爲S與步長爲1的差別。
如上圖,上面是步長爲1時的卷積結果,下面是步長爲2時的卷積結果。我們可以看出,因爲步長爲2,得到的feature map跳過了步長爲1時相應的部分。因此,當我們反向計算誤差項時,我們可以對步長爲S的sensitivity map相應的位置進行補0,將其『還原』成步長爲1時的sensitivity map,再用式8進行求解。
當輸入深度爲D時,filter的深度也必須爲D,層的通道只與filter的通道的權重進行計算。因此,反向計算誤差項時,我們可以使用式8,用filter的第通道權重對第層sensitivity map進行卷積,得到第層通道的sensitivity map。如下圖所示:
filter數量爲N時,輸出層的深度也爲N,第個filter卷積產生輸出層的第個feature map。由於第層每個加權輸入都同時影響了第層所有feature map的輸出值,因此,反向計算誤差項時,需要使用全導數公式。也就是,我們先使用第個filter對第層相應的第個sensitivity map進行卷積,得到一組N個層的偏sensitivity map。依次用每個filter做這種卷積,就得到D組偏sensitivity map。最後在各組之間將N個偏sensitivity map 按元素相加,得到最終的N個層的sensitivity map:
以上就是卷積層誤差項傳遞的算法,如果讀者還有所困惑,可以參考後面的代碼實現來理解。
我們要在得到第層sensitivity map的情況下,計算filter的權重的梯度,由於卷積層是權重共享的,因此梯度的計算稍有不同。
如上圖所示,是第層的輸出,是第層filter的權重,是第層的sensitivity map。我們的任務是計算的梯度,即。
爲了計算偏導數,我們需要考察權重對的影響。權重項通過影響的值,進而影響。我們仍然通過幾個具體的例子來看權重項對的影響,然後再從中總結出規律。
例1,計算:
從上面的公式看出,由於權值共享,權值對所有的都有影響。是、、...的函數,而、、...又是的函數,根據全導數公式,計算就是要把每個偏導數都加起來:
例2,計算:
通過查看與的關係,我們很容易得到:
實際上,每個權重項都是類似的,我們不一一舉例了。現在,是我們再次發揮想象力的時候,我們發現計算規律是:
也就是用sensitivity map作爲卷積核,在input上進行cross-correlation,如下圖所示:
最後,我們來看一看偏置項的梯度。通過查看前面的公式,我們很容易發現:
也就是偏置項的梯度就是sensitivity map所有誤差項之和。
對於步長爲S的卷積層,處理方法與傳遞**誤差項*是一樣的,首先將sensitivity map『還原』成步長爲1時的sensitivity map,再用上面的方法進行計算。
獲得了所有的梯度之後,就是根據梯度下降算法來更新每個權重。這在前面的文章中已經反覆寫過,這裏就不再重複了。
至此,我們已經解決了卷積層的訓練問題,接下來我們看一看Pooling層的訓練。
無論max pooling還是mean pooling,都沒有需要學習的參數。因此,在卷積神經網絡的訓練中,Pooling層需要做的僅僅是將誤差項傳遞到上一層,而沒有梯度的計算。
如下圖,假設第層大小爲4*4,pooling filter大小爲2*2,步長爲2,這樣,max pooling之後,第層大小爲2*2。假設第層的值都已經計算完畢,我們現在的任務是計算第層的值。
我們用表示第層的加權輸入;用表示第層的加權輸入。我們先來考察一個具體的例子,然後再總結一般性的規律。對於max pooling:
也就是說,只有區塊中最大的纔會對的值產生影響。我們假設最大的值是,則上式相當於:
那麼,我們不難求得下面幾個偏導數:
因此:
而:
現在,我們發現了規律:對於max pooling,下一層的誤差項的值會原封不動的傳遞到上一層對應區塊中的最大值所對應的神經元,而其他神經元的誤差項的值都是0。如下圖所示(假設、、、爲所在區塊中的最大輸出值):
我們還是用前面屢試不爽的套路,先研究一個特殊的情形,再擴展爲一般規律。
如上圖,我們先來考慮計算。我們先來看看如何影響。
根據上式,我們一眼就能看出來:
所以,根據鏈式求導法則,我們不難算出:
同樣,我們可以算出、、:
現在,我們發現了規律:對於mean pooling,下一層的誤差項的值會平均分配到上一層對應區塊中的所有神經元。如下圖所示:
上面這個算法可以表達爲高大上的克羅內克積(Kronecker product)的形式,有興趣的讀者可以研究一下。
其中,是pooling層filter的大小,、都是矩陣。
至此,我們已經把卷積層、Pooling層的訓練算法介紹完畢,加上上一篇文章講的全連接層訓練算法,您應該已經具備了編寫卷積神經網絡代碼所需要的知識。