1. 程式人生 > >3. CNN卷積網路-反向更新

3. CNN卷積網路-反向更新

1. 前言

如果讀者詳細的瞭解了DNN神經網路的反向更新,那對我們今天的學習會有很大的幫助。我們的CNN卷機網路中有3種網路結構。1. 卷積層,2.池化層,3.全連線層。全連線層的反向傳播的方式和DNN的反向傳播的方式是一樣的,因為DNN的所有層都是全連線的結構。卷機層和池化層下文會繼續講解。

2. 全連線反向更新

這裡先回顧下DNN的反向更新,我們進行反向更新主要是計算每一層的\(W,b\)的梯度。

\[ \frac{\partial J(W,b)}{\partial W^l} = \frac{\partial J(W,b,x,y)}{\partial z^l} \frac{\partial z^l}{\partial W^l} = \delta^{l}(a^{l-1})^T \]

\[ \frac{\partial J(W,b,x,y)}{\partial b^l} = \frac{\partial J(W,b)}{\partial z^l} \frac{\partial z^l}{\partial b^l} = \delta^{l} \]
我們現在的目標只要計算每層的\(\delta\),就可以算出每層的\(W,b\)的梯度。最後一層的\(\delta\)很好計算,即

\[ \delta^L = \frac{\partial J(W,b,x,y)}{\partial z^L} = (a^L-y)\odot \sigma^{'}(z^L) \]

如果我們能夠通過後一層的\(\delta\)

推算出前一層的\(\delta\)那就把問題完全解決了。

\[ \delta^{l} = \delta^{l+1}\frac{\partial z^{l+1}}{\partial z^{l}} = (W^{l+1})^T\delta^{l+1}\odot \sigma^{'}(z^l) \]
以上就是全連線層的反向更新的過程。需要明確的一點是以上的推到是有一個前提的:

\[ a^l = \sigma(z^l) = \sigma(W^la^{l-1} + b^l) \]
這個是前向傳播的公式。所以卷積層和池化層的前向傳播的公式不一樣,那在對反向更新中的引數求導的過程也會變化。

3. 卷積層的反向傳播

首先我們看下卷積層的前向傳播公式:
\[ a^l = \sigma(z^l) = \sigma(a^{l-1}*W^l + b) \]
其中的\(W^l\)是不是一個矩陣,矩陣的定義是2維的,而我們的\(W^l\)是一個張量,可以理解為多個矩陣的組合,或者理解為矩陣的陣列。

由於前向傳播公式的改變,卷積層求每層的\(\delta^{l}\)遞推方法肯定有所不同。又由於\(W\)用的運算是卷積,那麼計算卷積核的\(W,b\)的方式也不同。

3.1 求\(\delta^l\)的遞推公式

我們先求\(\delta^l\),它的遞推公式還是DNN中的那個。

\[ \delta^{l} = \frac{\partial J(W,b)}{\partial z^l} = \frac{\partial J(W,b)}{\partial z^{l+1}}\frac{\partial z^{l+1}}{\partial z^{l}} = \delta^{l+1}\frac{\partial z^{l+1}}{\partial z^{l}}\;\;\;\;\;\;(1) \]
因此和DNN一樣,計算\(\delta^l\)的任務就轉化成了計算\(\frac{\partial z^{l+1}}{\partial z^{l}}\),那捲積層中的\(\frac{\partial z^{l+1}}{\partial z^{l}}\)怎麼計算呢?

\[ z^l = a^{l-1}*W^l +b^l =\sigma(z^{l-1})*W^l +b^l \]
所以有

\[ \delta^{l-1} = \delta^{l}\frac{\partial z^{l}}{\partial z^{l-1}} = \delta^{l}*rot180(W^{l}) \odot \sigma^{'}(z^{l-1}) \]
這裡的式子其實和DNN的類似,區別在於對於含有卷積的式子求導時,卷積核被旋轉了180度。即式子中的\(rot180()\),翻轉180度的意思是上下翻轉一次,接著左右翻轉一次。在DNN中這裡只是矩陣的轉置。

3.2 已知\(\delta^l\),求\(W,b\)的梯度

卷積層\(z\)\(W,b\)的關係為:

\[ z^l = a^{l-1}*W^l +b \]
則有帶入(1)中得到:

\[ \frac{\partial J(W,b)}{\partial W^{l}} = \frac{\partial J(W,b)}{\partial z^{l}}\frac{\partial z^{l}}{\partial W^{l}} =a^{l-1} *\delta^l \]
其中的運算子\(*\)和前向傳播公式是一樣的,是卷積的過程。可以把張量展開。

\[ \frac{\partial J(W,b)}{\partial W^{l}} =\left( \begin{array}{ccc} a^{l-1}_{11}&a^{l-1}_{12}&a^{l-1}_{13}&a^{l-1}_{14} \\ a^{l-1}_{21}&a^{l-1}_{22}&a^{l-1}_{23}&a^{l-1}_{24} \\ a^{l-1}_{31}&a^{l-1}_{32}&a^{l-1}_{33}&a^{l-1}_{34} \\ a^{l-1}_{41}&a^{l-1}_{42}&a^{l-1}_{43}&a^{l-1}_{44} \end{array} \right) * \left( \begin{array}{ccc} \delta^{l}_{11}& \delta^{l}_{12} \\ \delta^{l}_{21}&\delta^{l}_{22} \end{array} \right) \]
\(\delta^l\)當作卷積核,去掃描\(a^{l-1}\)的張量,就得出了\(\frac{\partial J(W,b)}{\partial W^{l}}\)的梯度。

而對於\(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} \]

4. 池化層的反向更新

在前向傳播演算法時,池化層一般我們會用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^l_k\)做還原,即變成

\[ \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}}\)的值:

\[ \frac{\partial J(W,b)}{\partial a_k^{l-1}}= upsample(\delta_k^l) \]
所以\(\delta_k^{l-1}\)為:

\[ \delta_k^{l-1} = \frac{\partial J(W,b)}{\partial a_k^{l-1}} \frac{\partial a_k^{l-1}}{\partial z_k^{l-1}} = upsample(\delta_k^l) \odot \sigma^{'}(z_k^{l-1}) \]

5. 總結

以上就是CNN卷積網路的反向更新的過程,CNN卷積網路的更新和DNN還是有很大的不同,需要讀者仔細思考這個過程,最好找個簡單的例子能夠手推一下整個過程,能夠對整個過程有更深刻的理解。

(歡迎轉載,轉載請註明出處。歡迎溝通交流: [email protected]