卷積神經網絡(CNN)反向傳播算法

    在卷積神經網絡(CNN)前向傳播算法中,咱們對CNN的前向傳播算法作了總結,基於CNN前向傳播算法的基礎,咱們下面就對CNN的反向傳播算法作一個總結。在閱讀本文前,建議先研究DNN的反向傳播算法:深度神經網絡(DNN)反向傳播算法(BP)html

1. 回顧DNN的反向傳播算法

    咱們首先回顧DNN的反向傳播算法。在DNN中,咱們是首先計算出輸出層的$\delta^L$:$$\delta^L = \frac{\partial J(W,b)}{\partial z^L} = \frac{\partial J(W,b)}{\partial a^L}\odot \sigma^{'}(z^L)$$git

    利用數學概括法,用$\delta^{l+1}$的值一步步的向前求出第l層的$\delta^l$,表達式爲:$$\delta^{l} = (\frac{\partial z^{l+1}}{\partial z^{l}})^T\delta^{l+1} = (W^{l+1})^T\delta^{l+1}\odot \sigma^{'}(z^l)$$github

    有了$\delta^l$的表達式,從而求出$W,b$的梯度表達式:$$\frac{\partial J(W,b)}{\partial W^l}  = \delta^{l}(a^{l-1})^T$$$$\frac{\partial J(W,b,x,y)}{\partial b^l} = = \delta^{l}$$算法

    有了$W,b$梯度表達式,就能夠用梯度降低法來優化$W,b$,求出最終的全部$W,b$的值。網絡

    如今咱們想把一樣的思想用到CNN中,很明顯,CNN有些不一樣的地方,不能直接去套用DNN的反向傳播算法的公式。函數

2. CNN的反向傳播算法思想

    要套用DNN的反向傳播算法到CNN,有幾個問題須要解決:post

    1)池化層沒有激活函數,這個問題倒比較好解決,咱們能夠令池化層的激活函數爲$\sigma(z) = z$,即激活後就是本身自己。這樣池化層激活函數的導數爲1.優化

    2)池化層在前向傳播的時候,對輸入進行了壓縮,那麼咱們如今須要向前反向推導$\delta^{l-1}$,這個推導方法和DNN徹底不一樣。htm

    3) 卷積層是經過張量卷積,或者說若干個矩陣卷積求和而得的當前層的輸出,這和DNN很不相同,DNN的全鏈接層是直接進行矩陣乘法獲得當前層的輸出。這樣在卷積層反向傳播的時候,上一層的$\delta^{l-1}$遞推計算方法確定有所不一樣。blog

    4)對於卷積層,因爲$W$使用的運算是卷積,那麼從$\delta^l$推導出該層的全部卷積核的$W,b$的方式也不一樣。

    從上面能夠看出,問題1比較好解決,可是問題2,3,4就須要好好的動一番腦筋了,而問題2,3,4也是解決CNN反向傳播算法的關鍵所在。另外你們要注意到的是,DNN中的$a_l,z_l$都只是一個向量,而咱們CNN中的$a_l,z_l$都是一個張量,這個張量是三維的,即由若干個輸入的子矩陣組成。

    下面咱們就針對問題2,3,4來一步步研究CNN的反向傳播算法。

    在研究過程當中,須要注意的是,因爲卷積層能夠有多個卷積核,各個卷積核的處理方法是徹底相同且獨立的,爲了簡化算法公式的複雜度,咱們下面提到卷積核都是卷積層中若干卷積核中的一個。

3. 已知池化層的$\delta^l$,推導上一隱藏層的$\delta^{l-1}$   

    咱們首先解決上面的問題2,若是已知池化層的$\delta^l$,推導出上一隱藏層的$\delta^{l-1}$。

    在前向傳播算法時,池化層通常咱們會用MAX或者Average對輸入進行池化,池化的區域大小已知。如今咱們反過來,要從縮小後的偏差$\delta^l$,還原前一次較大區域對應的偏差。

    在反向傳播時,咱們首先會把$\delta^l$的全部子矩陣矩陣大小還原成池化以前的大小,而後若是是MAX,則把$\delta^l$的全部子矩陣的各個池化局域的值放在以前作前向傳播算法獲得最大值的位置。若是是Average,則把$\delta^l$的全部子矩陣的各個池化局域的值取平均後放在還原後的子矩陣位置。這個過程通常叫作upsample。

    用一個例子能夠很方便的表示:假設咱們的池化區域大小是2x2。$\delta^l$的第k個子矩陣爲:$$\delta_k^l =
\left( \begin{array}{ccc}
2& 8 \\
4& 6 \end{array} \right)$$

    因爲池化區域爲2x2,咱們先講$\delta_k^l$作還原,即變成:$$
\left( \begin{array}{ccc}
0&0&0&0 \\ 0&2& 8&0 \\ 0&4&6&0 \\
0&0&0&0 \end{array} \right)$$

     若是是MAX,假設咱們以前在前向傳播時記錄的最大值位置分別是左上,右下,右上,左下,則轉換後的矩陣爲:$$
\left( \begin{array}{ccc}
2&0&0&0 \\ 0&0& 0&8 \\ 0&4&0&0 \\
0&0&6&0 \end{array} \right)$$

    若是是Average,則進行平均:轉換後的矩陣爲:$$
\left( \begin{array}{ccc}
0.5&0.5&2&2 \\ 0.5&0.5&2&2 \\ 1&1&1.5&1.5 \\
1&1&1.5&1.5 \end{array} \right)$$

    這樣咱們就獲得了上一層 $\frac{\partial J(W,b)}{\partial a_k^{l-1}} $的值,要獲得$\delta_k^{l-1}$:$$\delta_k^{l-1} = (\frac{\partial  a_k^{l-1}}{\partial z_k^{l-1}})^T\frac{\partial J(W,b)}{\partial a_k^{l-1}}  = upsample(\delta_k^l) \odot \sigma^{'}(z_k^{l-1})$$

    其中,upsample函數完成了池化偏差矩陣放大與偏差從新分配的邏輯。

    咱們歸納下,對於張量$\delta^{l-1}$,咱們有:$$\delta^{l-1} =  upsample(\delta^l) \odot \sigma^{'}(z^{l-1})$$

4. 已知卷積層的$\delta^l$,推導上一隱藏層的$\delta^{l-1}$  

    對於卷積層的反向傳播,咱們首先回憶下卷積層的前向傳播公式:$$  a^l= \sigma(z^l) = \sigma(a^{l-1}*W^l +b^l) $$

    其中$n\_in$爲上一隱藏層的輸入子矩陣個數。

    在DNN中,咱們知道$\delta^{l-1}$和$\delta^{l}$的遞推關係爲:$$\delta^{l} = \frac{\partial J(W,b)}{\partial z^l} =(\frac{\partial z^{l+1}}{\partial z^{l}})^T \frac{\partial J(W,b)}{\partial z^{l+1}} =(\frac{\partial z^{l+1}}{\partial z^{l}})^T\delta^{l+1}$$

    所以要推導出$\delta^{l-1}$和$\delta^{l}$的遞推關係,必須計算$\frac{\partial z^{l}}{\partial z^{l-1}}$的梯度表達式。

    注意到$z^{l}$和$z^{l-1}$的關係爲:$$z^l = a^{l-1}*W^l +b^l =\sigma(z^{l-1})*W^l +b^l  $$

    所以咱們有:$$\delta^{l-1} =  (\frac{\partial z^{l}}{\partial z^{l-1}})^T\delta^{l} = \delta^{l}*rot180(W^{l}) \odot  \sigma^{'}(z^{l-1}) $$

    這裏的式子其實和DNN的相似,區別在於對於含有卷積的式子求導時,卷積核被旋轉了180度。即式子中的$rot180()$,翻轉180度的意思是上下翻轉一次,接着左右翻轉一次。在DNN中這裏只是矩陣的轉置。那麼爲何呢?因爲這裏都是張量,直接推演參數太多了。咱們以一個簡單的例子說明爲啥這裏求導後卷積核要翻轉。

    假設咱們$l-1$層的輸出$a^{l-1}$是一個3x3矩陣,第$l$層的卷積核$W^l$是一個2x2矩陣,採用1像素的步幅,則輸出$z^{l}$是一個2x2的矩陣。咱們簡化$b^l都是0$,則有$$a^{l-1}*W^l = z^{l}$$

    咱們列出$a,W,z$的矩陣表達式以下:$$
\left( \begin{array}{ccc}
a_{11}&a_{12}&a_{13} \\ a_{21}&a_{22}&a_{23}\\
a_{31}&a_{32}&a_{33} \end{array} \right)    *  \left( \begin{array}{ccc}
w_{11}&w_{12}\\
w_{21}&w_{22} \end{array} \right) = \left( \begin{array}{ccc}
z_{11}&z_{12}\\
z_{21}&z_{22} \end{array} \right)$$

    利用卷積的定義,很容易得出:$$z_{11} = a_{11}w_{11} + a_{12}w_{12} + a_{21}w_{21} +   a_{22}w_{22} $$$$z_{12} = a_{12}w_{11} + a_{13}w_{12} + a_{22}w_{21} +   a_{23}w_{22} $$$$z_{21} = a_{21}w_{11} + a_{22}w_{12} + a_{31}w_{21} +   a_{32}w_{22} $$$$z_{22} = a_{22}w_{11} + a_{23}w_{12} + a_{32}w_{21} +   a_{33}w_{22} $$

    接着咱們模擬反向求導:$$\nabla a^{l-1} = \frac{\partial J(W,b)}{\partial a^{l-1}} = ( \frac{\partial z^{l}}{\partial a^{l-1}})^T\frac{\partial J(W,b)}{\partial z^{l}} =(\frac{\partial z^{l}}{\partial a^{l-1}})^T \delta^{l} $$

    從上式能夠看出,對於$a^{l-1}$的梯度偏差$\nabla a^{l-1}$,等於第$l$層的梯度偏差乘以$\frac{\partial z^{l}}{\partial a^{l-1}}$,而$\frac{\partial z^{l}}{\partial a^{l-1}}$對應上面的例子中相關聯的$w$的值。假設咱們的$z$矩陣對應的反向傳播偏差是$\delta_{11}, \delta_{12}, \delta_{21}, \delta_{22}$組成的2x2矩陣,則利用上面梯度的式子和4個等式,咱們能夠分別寫出$\nabla a^{l-1}$的9個標量的梯度。

    好比對於$a_{11}$的梯度,因爲在4個等式中$a_{11}$只和$z_{11}$有乘積關係,從而咱們有:$$ \nabla a_{11} = \delta_{11}w_{11}$$

    對於$a_{12}$的梯度,因爲在4個等式中$a_{12}$和$z_{12},z_{11}$有乘積關係,從而咱們有:$$ \nabla a_{12} = \delta_{11}w_{12} + \delta_{12}w_{11}$$

    一樣的道理咱們獲得:$$ \nabla a_{13} = \delta_{12}w_{12} $$$$\nabla a_{21} = \delta_{11}w_{21} + \delta_{21}w_{11}$$$$\nabla a_{22} = \delta_{11}w_{22} + \delta_{12}w_{21} + \delta_{21}w_{12} + \delta_{22}w_{11}  $$$$ \nabla a_{23} = \delta_{12}w_{22} + \delta_{22}w_{12}$$$$ \nabla a_{31} = \delta_{21}w_{21}$$$$ \nabla a_{32} = \delta_{21}w_{22} + \delta_{22}w_{21}$$$$ \nabla a_{33} = \delta_{22}w_{22} $$  

    這上面9個式子其實能夠用一個矩陣卷積的形式表示,即:$$
\left( \begin{array}{ccc}
0&0&0&0 \\ 0&\delta_{11}& \delta_{12}&0 \\ 0&\delta_{21}&\delta_{22}&0 \\
0&0&0&0 \end{array} \right) * \left( \begin{array}{ccc}
w_{22}&w_{21}\\
w_{12}&w_{11} \end{array} \right)  = \left( \begin{array}{ccc}
\nabla a_{11}&\nabla a_{12}&\nabla a_{13} \\ \nabla a_{21}&\nabla a_{22}&\nabla a_{23}\\
\nabla a_{31}&\nabla a_{32}&\nabla a_{33} \end{array} \right)$$

     爲了符合梯度計算,咱們在偏差矩陣周圍填充了一圈0,此時咱們將卷積核翻轉後和反向傳播的梯度偏差進行卷積,就獲得了前一次的梯度偏差。這個例子直觀的介紹了爲何對含有卷積的式子反向傳播時,卷積核要翻轉180度的緣由。

    以上就是卷積層的偏差反向傳播過程。

5. 已知卷積層的$\delta^l$,推導該層的$W,b$的梯度    

    好了,咱們如今已經能夠遞推出每一層的梯度偏差$\delta^l$了,對於全鏈接層,能夠按DNN的反向傳播算法求該層$W,b$的梯度,而池化層並無$W,b$,也不用求$W,b$的梯度。只有卷積層的$W,b$須要求出。

    注意到卷積層$z$和$W,b$的關係爲:$$z^l = a^{l-1}*W^l +b$$

    所以咱們有:$$\frac{\partial J(W,b)}{\partial W^{l}}=a^{l-1} *\delta^l$$

    注意到此時卷積核並無反轉,主要是此時是層內的求導,而不是反向傳播到上一層的求導。具體過程咱們能夠分析一下。

    和第4節同樣的一個簡化的例子,這裏輸入是矩陣,不是張量,那麼對於第l層,某個個卷積核矩陣W的導數能夠表示以下:$$\frac{\partial J(W,b)}{\partial W_{pq}^{l}} = \sum\limits_i\sum\limits_j(\delta_{ij}^la_{i+p-1,j+q-1}^{l-1})$$

    假設咱們輸入$a$是4x4的矩陣,卷積核$W$是3x3的矩陣,輸出$z$是2x2的矩陣,那麼反向傳播的$z$的梯度偏差$\delta$也是2x2的矩陣。

    那麼根據上面的式子,咱們有:$$\frac{\partial J(W,b)}{\partial W_{11}^{l}} = a_{11}\delta_{11} + a_{12}\delta_{12} + a_{21}\delta_{21} +  a_{22}\delta_{22}$$

$$\frac{\partial J(W,b)}{\partial W_{12}^{l}} = a_{12}\delta_{11} + a_{13}\delta_{12} + a_{22}\delta_{21} +  a_{23}\delta_{22}$$

$$\frac{\partial J(W,b)}{\partial W_{13}^{l}} = a_{13}\delta_{11} + a_{14}\delta_{12} + a_{23}\delta_{21} +  a_{24}\delta_{22}$$

$$\frac{\partial J(W,b)}{\partial W_{21}^{l}} = a_{21}\delta_{11} + a_{22}\delta_{12} + a_{31}\delta_{21} +  a_{32}\delta_{22}$$

    最終咱們能夠一共獲得9個式子。整理成矩陣形式後可得:

$$\frac{\partial J(W,b)}{\partial W^{l}} =\left( \begin{array}{ccc} a_{11}&a_{12}&a_{13}&a_{14} \\ a_{21}&a_{22}&a_{23}&a_{24} \\ a_{31}&a_{32}&a_{33}&a_{34} \\
a_{41}&a_{42}&a_{43}&a_{44} \end{array} \right) * \left( \begin{array}{ccc}
\delta_{11}& \delta_{12} \\ \delta_{21}&\delta_{22} \end{array} \right)  $$

    從而能夠清楚的看到此次咱們爲何沒有反轉的緣由。

    而對於b,則稍微有些特殊,由於$\delta^l$是高維張量,而$b$只是一個向量,不能像DNN那樣直接和$\delta^l$相等。一般的作法是將$\delta^l$的各個子矩陣的項分別求和,獲得一個偏差向量,即爲$b$的梯度:$$\frac{\partial J(W,b)}{\partial b^{l}} = \sum\limits_{u,v}(\delta^l)_{u,v}$$

6. CNN反向傳播算法總結

    如今咱們總結下CNN的反向傳播算法,以最基本的批量梯度降低法爲例來描述反向傳播算法。

    輸入:m個圖片樣本,CNN模型的層數L和全部隱藏層的類型,對於卷積層,要定義卷積核的大小K,卷積核子矩陣的維度F,填充大小P,步幅S。對於池化層,要定義池化區域大小k和池化標準(MAX或Average),對於全鏈接層,要定義全鏈接層的激活函數(輸出層除外)和各層的神經元個數。梯度迭代參數迭代步長$\alpha$,最大迭代次數MAX與中止迭代閾值$\epsilon$

    輸出:CNN模型各隱藏層與輸出層的$W,b$

    1) 初始化各隱藏層與輸出層的各$W,b$的值爲一個隨機值。

      2)for iter to 1 to MAX:

    2-1) for i =1 to m:

      a) 將CNN輸入$a^1$設置爲$x_i$對應的張量

      b) for $l$=2 to L-1,根據下面3種狀況進行前向傳播算法計算:

      b-1) 若是當前是全鏈接層:則有$a^{i,l} = \sigma(z^{i,l}) = \sigma(W^la^{i,l-1} + b^{l})$

      b-2) 若是當前是卷積層:則有$a^{i,l} = \sigma(z^{i,l}) = \sigma(W^l*a^{i,l-1} + b^{l})$

      b-3) 若是當前是池化層:則有$ a^{i,l}= pool(a^{i,l-1})$, 這裏的pool指按照池化區域大小k和池化標準將輸入張量縮小的過程。

      c) 對於輸出層第L層: $ a^{i,L}= softmax(z^{i,L}) = softmax(W^{L}a^{i,L-1} +b^{L})$

      c) 經過損失函數計算輸出層的$\delta^{i,L}$

      d) for $l$= L-1 to 2, 根據下面3種狀況進行進行反向傳播算法計算:

      d-1)  若是當前是全鏈接層:$\delta^{i,l} =  (W^{l+1})^T\delta^{i,l+1}\odot \sigma^{'}(z^{i,l})$

      d-2) 若是當前是卷積層:$\delta^{i,l} = \delta^{i,l+1}*rot180(W^{l+1}) \odot  \sigma^{'}(z^{i,l}) $

      d-3) 若是當前是池化層:$\delta^{i,l} =  upsample(\delta^{i,l+1}) \odot \sigma^{'}(z^{i,l})$

    2-2) for $l$ = 2 to L,根據下面2種狀況更新第$l$層的$W^l,b^l$:

      2-2-1) 若是當前是全鏈接層:$W^l = W^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}(a^{i, l-1})^T $, $b^l = b^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}$

      2-2-2) 若是當前是卷積層,對於每個卷積核有:$W^l = W^l -\alpha \sum\limits_{i=1}^m \delta^{i,l}*a^{i, l-1} $, $b^l = b^l -\alpha \sum\limits_{i=1}^m \sum\limits_{u,v}(\delta^{i,l})_{u,v}$

    2-3) 若是全部$W,b$的變化值都小於中止迭代閾值$\epsilon$,則跳出迭代循環到步驟3。

    3) 輸出各隱藏層與輸出層的線性關係係數矩陣$W$和偏倚向量$b$。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com) 

參考資料:

1) Neural Networks and Deep Learning by By Michael Nielsen

2) Deep Learning, book by Ian Goodfellow, Yoshua Bengio, and Aaron Courville

3) UFLDL Tutorial

4)CS231n Convolutional Neural Networks for Visual Recognition, Stanford

相關文章
相關標籤/搜索