卷積神經網絡的前向傳播
首先我們來看一個最簡單的卷積神經網絡:
1.輸入層---->卷積層
以上一節的例子爲例,輸入是一個4*4 的image,經過兩個2*2的卷積核進行卷積運算後,變成兩個3*3的feature_map
以卷積核filter1爲例(stride = 1 ):
計算第一個卷積層神經元o11的輸入:
神經元o11的輸出:(此處使用Relu激活函數)
其他神經元計算方式相同
2.卷積層---->池化層
計算池化層m11 的輸入(取窗口爲 2 * 2),池化層沒有激活函數
3.池化層---->全連接層
池化層的輸出到flatten層把所有元素「拍平」,然後到全連接層。
4.全連接層---->輸出層
全連接層到輸出層就是正常的神經元與神經元之間的鄰接相連,通過softmax函數計算後輸出到output,得到不同類別的概率值,輸出概率值最大的即爲該圖片的類別。
卷積神經網絡的反向傳播
傳統的神經網絡是全連接形式的,如果進行反向傳播,只需要由下一層對前一層不斷的求偏導,即求鏈式偏導就可以求出每一層的誤差敏感項,然後求出權重和偏置項的梯度,即可更新權重。而卷積神經網絡有兩個特殊的層:卷積層和池化層。池化層輸出時不需要經過激活函數,是一個滑動窗口的最大值,一個常數,那麼它的偏導是1。池化層相當於對上層圖片做了一個壓縮,這個反向求誤差敏感項時與傳統的反向傳播方式不同。從卷積後的feature_map反向傳播到前一層時,由於前向傳播時是通過卷積核做卷積運算得到的feature_map,所以反向傳播與傳統的也不一樣,需要更新卷積核的參數。下面我們介紹一下池化層和卷積層是如何做反向傳播的。
在介紹之前,首先回顧一下傳統的反向傳播方法:
1.通過前向傳播計算每一層的輸入值neti,j
(如卷積後的feature_map的第一個神經元的輸入:neti11)
2.反向傳播計算每個神經元的誤差項δi,j
,δi,j=∂E∂neti,j,其中E爲損失函數計算得到的總體誤差,可以用平方差,交叉熵等表示。
3.計算每個神經元權重wi,j
的梯度,ηi,j=∂E∂neti,j⋅∂neti,j∂wi,j=δi,j⋅outi,j4.更新權重 wi,j=wi,j−λ⋅ηi,j
(其中λ爲學習率)
卷積層的反向傳播
由前向傳播可得:
neti11
表示上一層的輸入, outo11表示上一層的輸出
首先計算卷積的上一層的第一個元素i11
的誤差項δ11:
)
注:原來這裏寫的是計算輸入層的誤差項是不準確的,這裏的i11
表示的是卷積層的上一層即可。
先計算∂E∂i11
此處我們並不清楚∂E∂i11
怎麼算,那可以先把input層通過卷積核做完卷積運算後的輸出feature_map寫出來:
然後依次對輸入元素ii,j
求偏導
i11
的偏導:
i12
的偏導:
i13
的偏導:
i21
的偏導:
i22
的偏導:
觀察一下上面幾個式子的規律,歸納一下,可以得到如下表達式:
圖中的卷積核進行了180°翻轉,與這一層的誤差敏感項矩陣deltai,j)
周圍補零後的矩陣做卷積運算後,就可以得到∂E∂i11,即
∂E∂ii,j=∑m⋅∑nhm,nδi+m,j+n
第一項求完後,我們來求第二項∂i11∂neti11
此時我們的誤差敏感矩陣就求完了,得到誤差敏感矩陣後,即可求權重的梯度。
由於上面已經寫出了卷積層的輸入ne∑nhm,nδi+m,j+n⋅f′(neti11)(12)
此時我們的誤差敏感矩陣就求完了,得到誤差敏感矩陣後,即可求權重的梯度。
由於上面已經寫出了卷積層的輸入neto11
與權重hi,j之間的表達式,所以可以直接求出: