BP算法,在深度神經網絡的發展中有着舉足輕重的地位,對於反向傳播算法的推導過程,各種資料介紹可謂是多不勝數。但,由於深度神經網絡的復雜性,要比較深刻的理解反向傳播算法還是需要自己手動的推導一遍。
本文以前篇深度學習與計算機視覺: 深度學習必知基本概念以及鏈式求導介紹了神經網絡的反向傳播中的鏈式求導法則為基礎,以一個三層的神經網絡為例 ,一步步的推導,最終歸納出反向傳播算法四個基本方程。
在前文中,利用鏈式求導法則,得到如下結果
\[\begin{align*} \frac{\partial e_{o1}}{\partial w_{11}^2} &=(a_1^3 - y_1) \cdot sigmoid(z_1^3)(1 - sigmoid(z_1^3))\cdot a_1^2 \\ \frac{\partial e_{o1}}{\partial b_1^3} &= (a_1^3 - y_1) \cdot sigmoid(z_1^3)(1 - sigmoid(z_1^3)) \\ \frac{\partial e_{o1}}{\partial w_{11}^1}&= (a_1^3 - y_1) \cdot sigmoid(z_1^3)(1 - sigmoid(z_1^3)\cdot w_{11}^3 \cdot sigmoid(z_1^2)(1 - sigmoid(z_1^2))\cdot a_1^1 \\ \frac{\partial e_{o1}}{\partial b_1^2} &= (a_1^3 - y_1) \cdot sigmoid(z_1^3)(1 - sigmoid(z_1^3)\cdot w_{11}^3 \cdot sigmoid(z_1^2)(1 - sigmoid(z_1^2)) \end{align*} \]
這還只是很小神經網絡中,每層第一個神經元的求梯度過程,如果有成百上千的神經元利用上述單純的鏈式求導法則去計算各個權值和偏置的梯度,無疑是很困難的。
不過好消息是,上面的公式中有很大一部分的重復計算過程,而神經網絡也是個疊加的結構,利用上述的重復的部分,就能夠很好的完成反向傳播的計算過程。 這也是有名的反向傳播四個基本方程所做的事情。
本文就以上述的推導為基礎,在知道 反向傳播四個基本方程的前提下,推導這四個基本方程的過程。
引入中間變量\(\delta_j^l\)
反向傳播的最終目的是為了求誤差關於權值和神經元的權值和偏置的導數,即\(\frac{\partial E}{\partial w_{jk}^l}\)和\(\frac{\partial E}{\partial b_j^l}\)。為了能夠利用上面提到的各個偏導數計算的重復元素,這里引入個中間變量\(\delta_j^l\)。
使用\(\sigma\)表示激活函數\(sigmoid\),\(\sigma'\)表示該函數的導數,來重寫下上面的公式
\[\begin{align*} \frac{\partial e_{o1}}{\partial w_{11}^3} &=(a_1^3 - y_1) \cdot \sigma'(z_1^3)\cdot a_1^2 \\ \frac{\partial e_{o1}}{\partial w_{12}^3} &=(a_1^3 - y_1) \cdot \sigma'(z_1^3)\cdot a_2^2 \\ \frac{\partial e_{o1}}{\partial w_{21}^3} &=(a_1^3 - y_1) \cdot \sigma'(z_2^3)\cdot a_1^2 \\ \frac{\partial e_{o1}}{\partial w_{12}^3} &=(a_1^3 - y_1) \cdot \sigma'(z_2^3)\cdot a_2^2 \\ \frac{\partial e_{o1}}{\partial b_1^3} &= (a_1^3 - y_1) \cdot \sigma'(z_1^3) \\ \frac{\partial e_{o1}}{\partial b_2^3} &= (a_1^3 - y_1) \cdot \sigma'(z_2^3) \\ \end{align*} \]
這里設中間變量\(\delta_1^3,\delta_2^3\)
\[\delta_1^3 = (a_1^3 - y_1) \cdot \sigma'(z_1^3) \\ \delta_2^3 = (a_2^3 - y_2)\cdot \sigma'(z_2^3) \]
可以得到如下結果:
- 權值\(W^3\)的偏導數,輸出層到隱藏層之間的權值。
\[\left[ \begin{array}{cc} \frac{\partial e_{o}}{\partial w_{11}^3} & \frac{\partial e_{o}}{\partial w_{12}^3} \\ \frac{\partial e_{o}}{\partial w_{21}^3} &\frac{\partial e_{o}}{\partial w_{22}^3} \end{array}\right] = \left[ \begin{array}{cc}\delta_1^3\cdot a_1^2 & \delta_1^3\cdot a_2^2 \\ \delta_2^3 \cdot a_1^2 & \delta_2^3 \cdot a_2^2\end{array} \right] \]
\[\left[ \begin{array}{c} \frac{\partial e_{o}}{b_1^3} \\ \frac{\partial e_{o}}{b_2^3} \end{array} \right] = \left[ \begin{array}{c} \delta_1^3 \\\delta_2^3 \end{array} \right] \]
有了上面的公式,這對於輸出層和隱藏層之間的權值偏導數求起來就很簡單了。只需要求出\(\delta_1^3,\delta_2^3\),再乘以神經元相應的輸入即可。而\(\delta_1^3,\delta_2^3\)的計算也很簡單,前部分是輸出代價函數的導數,后部分中的\(z_j^3\)為神經元的輸入的加權和,在計算正向傳播的過程可以緩存下來。
上面計算的是輸出層和隱藏層之間權值和偏置的導數,利用中間變量\(\delta_j^3\)不但是整個計算很清晰,而且能夠利用正向傳播的中間結果,加快反向傳播的計算。
\(\delta^l\)的遞推公式
這里不禁就有個疑問,對於隱藏層和輸入層之間的權值和偏置是不是也可以利用類似的中間變量\(\delta_j^2\)呢。答案是肯定的。
首先來分析下 \(\delta_j^3\)的組成,
\[\delta_j^3 = (a_j^3 - y_j) \cdot \sigma'(z_j^3) \]
很明顯,前面部分是輸出層的誤差 \(e_{oj} = \frac{1}{2}(a_j^3 - y_j)^2\)關於\(a_j^3\)的偏導數;后面部分則是神經元的輸出\(a_j^3 = \sigma(z_j^3)\)關於加權后的\(z_j^3\)導數,應用鏈式求導法則
\[\begin{align*} \delta_j^3 &= \frac{\partial e_{oj}}{\partial a_j^3} \cdot \frac{\partial a_j^3}{z_j^3}\\ &= \frac{\partial e_{oj}}{z_j^3} \end{align*} \]
到這里,就可以很容易的得到,
\[\begin{align*} \delta_j^2 &= \frac{\partial e_o}{\partial z_j^2} \\ &= \sum_k^2\frac{\partial e_{ok}}{\partial z_j^2} \\ & = \frac{\partial e_{o1}}{\partial z_j^2} + \frac{\partial e_{o2}}{\partial z_j^2} \end{align*} \]
其中,\(e_o\)表示輸出層的誤差,\(z_j^2\)表示輸入到隱藏層加權后的值。 那么上式的意義就是輸出層最終的輸出誤差關於隱藏層加權后的偏導數。
注意上面的展開,是因為在輸出層\(e_{ok}\)只和第\(k\)個神經元有關,而往前傳播到了隱藏層,則隱藏層的所有神經元都有關。
有了上述的表達式,而且由正向傳播,可以知道\(z_j^3 = w_{j1}^3 a_1^2 + w_{j2}^3 a_2^2\),利用鏈式求導的方法,將其和\(\delta_j^3\)關聯起來。
\[\begin{align*} \delta_j^2 &= \frac{\partial e_{o1}}{\partial z_j^2} + \frac{\partial e_{o2}}{\partial z_j^2} \\ &= \frac{\partial e_{o1}}{\partial z_1^3} \cdot \frac{\partial z_1^3}{\partial a_j^2} \cdot \frac{\partial a_j^2}{\partial z_j^2} + \frac{\partial e_{o2}}{\partial z_2^3} \cdot \frac{\partial z_2^3}{\partial a_j^2} \cdot \frac{\partial a_j^2}{\partial z_j^2} \\ &= \delta_1^3 \cdot w_{1j}^3 \cdot \sigma'(z_j^2) + \delta_2^3 \cdot w_{2j}^3 \cdot \sigma'(z_j^2) \end{align*} \]
將上式按照矩陣的形式展開
\[\begin{align*} \left[\begin{array}{c}\delta_1^2 \\ \delta_2^2\end{array}\right] &= \left[\begin{array}{c}\delta_1^3 \cdot w_{11}^3 \cdot \sigma'(z_1^2) + \delta_2^3 \cdot w_{21}^3 \cdot \sigma'(z_1^2) \\ \delta_1^3 \cdot w_{12}^3 \cdot \sigma'(z_2^2) + \delta_2^3 \cdot w_{22}^3 \cdot \sigma'(z_2^2) \end{array}\right] \\ &= \left[\begin{array}{c} w_{11}^3 & w_{21}^3 \\ w_{12}^3 & w_{22}^3\end{array}\right] \cdot \left[\begin{array}{c}\delta_1^3 \\ \delta_2^3\end{array}\right] \odot \left[\begin{array}{c} \sigma'(z_1^2) \\ \sigma'(z_2^2)\end{array}\right] \end{align*} \]
令 $\delta^l =\left[\begin{array}{c}\delta_1^l \ \delta_2^l\end{array}\right] $ 則有
\[\delta^2 = (W^3)^T\delta^3\odot \sigma'(z^l) \]
在\(\delta^3\)已知的情況下上述公式的計算也很簡單,\((W^3)^T\)是輸出層和隱藏層之間的權值矩陣,\(\sigma'(z^l)\)是關於\(z^l\)的導數,\(z^l\)的值可以在正向傳播計算的過程中緩存下來。
現在可以將\(W^2\)的偏導數使用\(\delta^2\)的形式表達了
\[\left[ \begin{array}{cc} \frac{\partial e_{o}}{\partial w_{11}^2} & \frac{\partial e_{o}}{\partial w_{12}^2} \\ \frac{\partial e_{o}}{\partial w_{21}^2} & \frac{\partial e_{o}}{\partial w_{22}^2} \end{array}\right] = \left[ \begin{array}{cc}\delta_1^2\cdot a_1^1 & \delta_1^2\cdot a_2^1 \\ \delta_2^2 \cdot a_1^1 & \delta_2^2 \cdot a_2^1\end{array} \right] \]
偏置矩陣\(B^2\)的偏導數
\[\left[ \begin{array}{c} \frac{\partial e_{o}}{b_1^2} \\ \frac{\partial e_{o}}{b_2^2} \end{array} \right] = \left[ \begin{array}{c} \delta_2^3 \\\delta_2^3 \end{array} \right] \]
反向傳播的4個基本公式
在上面的推導過程中,使用的是一個3層神經網絡,每個層有兩個神經元。
對上面的推到過程,進行歸納。可以得到以下幾個公式
- 輸出層的誤差,\(\delta^L,(L= 3)\)
\[\delta^L = \frac{\partial e}{\partial a^L} \odot \sigma'(z^L) \tag{BP1} \]
- \(\delta^L\)和 \(\delta^{L-1}\)遞推關系
\[\delta^{L-1} = (W^L)^T\delta^L \odot \sigma'(z^{L-1}) \tag{BP2} \]
\[\frac{\partial e}{b_j^l} = \delta_j^l \tag{BP3} \]
\[\frac{\partial e}{w_{jk}^l} = \delta_j^l a_k^{l-1} \tag{BP4} \]
這樣在正向傳播的過程中,換成每個神經元的加權后的值\(z^l\)。
- 正向傳播的過程中對於每個\(l = 2,3,4,\cdots,L\)計算出\(z^l = W^la^{l-1} + b^l\)以及\(a^l = \sigma(z^l)\)
- 輸出層的誤差,根據公式\({BP1}\) 計算 \(\delta^L\)
- 反向誤差傳播,計算每個層的\(\delta^l\),根據公式\(BP2\)
- 偏置的梯度,根據公式\(BP3\)
- 權值矩陣的梯度,根據公式\(BP4\)
上述反向傳播四個基本方程的推導與證明,可以參看《神經網絡與深度學習》http://neuralnetworksanddeeplearning.com/
總結
花了幾天的時間,終於算是把深度學習的入門基礎概念以及反向傳播算法的總結完成了。
特別是在反向傳播算法的計算過程,本文是在已經知道四個基本方程的基礎上,以一個簡單的神經網絡為例,一步步的導出最后的四個基本方程,對反向傳播的過程有了個更深刻的理解。 看着那么復雜的求導過程,一步步的變成4個簡潔的數據公式,還是有點小興奮的...