在講解誤差反向傳播算法之前,我們來回顧一下信號在神經網絡中的流動過程。請細細體會,當輸入向量\(X\)輸入感知器時,第一次初始化權重向量\(W\)是隨機組成的,也可以理解成我們任意設置了初始值,並和輸入做點積運算,然后模型通過權重更新公式來計算新的權重值,更新后的權重值又接着和輸入相互作用,如此迭代多次,得到最終的權重。
信號向前傳播,權重的更新反向傳播,是這樣嗎?
是的,你的直覺沒錯,確實是反向傳播。
1. 前饋的實質
反向傳播這個術語經常被誤解為用於多層神經網絡的整個學習算法。實際上,反向傳播僅指用於計算梯度的方法,而另一種算法,例如隨機梯度下降,使用該梯度來進行學習。此外,反向傳播經常被誤解為僅適用於多層神經網絡,但是原則上它可以計算任何函數的導數(對於一些函數,正確的響應是報告函數的導數是未定義的)。
1.1 初始化權重和輸入信號
不如我們還是使用上一節矩陣乘法的列子來可視化的講解,這樣有助於我們去理解反向傳播。假設有如下三層網絡,輸入層、隱藏層、輸出層,現有一組信號\(X\)輸入網絡,輸入層和隱藏層的鏈接權重\(W_{input-hidden}\)和隱藏層與輸出層之間的權重\(W_{hidden-ouput}\)我們隨機初始化。為了清晰效果,我們僅標注了幾個權重,第一個輸入節點和中間隱藏層第一個節點之間的權重為\(w_{1,1}\) = 0.9,正如上圖中的神經網絡所示。同樣,你可以看到輸入的第二節點和隱藏層的第二節點之間的鏈接的權重為\(w_{2,2}\) = 0.8,隱藏層第三個節點和輸出層第二個節點之間鏈接的權重為\(w_{3,2}\) = 0.2......此命名方式前面解釋過,標注之后在分析反向傳播時可幫助我們理解。
圖5.2.1
輸入矩陣:
\[X=\begin{bmatrix} 0.9\\ 0.1\\ 0.8\end{bmatrix}\]
輸入層和隱藏層之間的連接權重:
\[W_{input-hidden}=\begin{bmatrix} 0.9 & 0.3&0.4 \\ 0.2& 0.8&0.2 \\ 0.8& 0.1&0.9 \end{bmatrix}\]
隱藏層和輸出層之間的連接權重:
\[W_{hidden-output}=\begin{bmatrix} 0.3 & 0.7&0.5 \\ 0.6& 0.5&0.2 \\ \end{bmatrix}\]
1.2 輸入層到隱藏層
初始值定義好以后,開始計算輸入到隱藏層的組合調節輸入值\(X_{hidden}\)。
\[X_{hidden} = W_{input_hidden} \cdot X \]
此處的矩陣乘法還是交由計算機來執行,計算出的答案如下:
\[X_{hidden} =\begin{bmatrix} 0.9 & 0.3&0.4 \\ 0.2& 0.8&0.2 \\ 0.8& 0.1&0.9 \end{bmatrix} \cdot \begin{bmatrix} 0.9\\ 0.1\\ 0.8\end{bmatrix}\]
\[X_{hidden} =\begin{bmatrix} 1.16\\ 0.42\\ 0.62\end{bmatrix}\]
別着急往下走,讓我們來整理一下網絡的信號流動情況,\(X_{hidden}\)作為第一層的輸出,第二層的輸入已經正確求解,現在它准備進入隱藏層。
圖5.2.2
\(X_{hidden}\)一進入隱藏層,我們就對\(X_{hidden}\)的這些節點使用S激活函數,使其變得更加自然,並且我們把經過S函數處理后的這組輸出信號命名為\(O_{hidden}\)。
\[O_{hidden}=Sigmoid(X_{hidden})=Sigmoid(\begin{bmatrix} 1.16\\ 0.42\\ 0.62\end{bmatrix})=\begin{bmatrix} 0.761\\ 0.603\\ 0.650\end{bmatrix}\]
1.3 隱藏層到輸出層
讓我們再次可視化這些輸入到第二層隱藏層的組合調節輸入。現在信號已經向前流動到了第二層,下一步當然是計算第三層的輸出信號\(X_{output}\)(還未經過S函數的輸出信號),計算的方法和前面一樣,沒有什么區別,不管我們的網絡是幾層,這種方法都適用。
圖5.2.3
於是,我們有:
\[X_{output}=W_{hidden-output} \cdot O_{hidden}=\begin{bmatrix} 0.3 & 0.7&0.5 \\ 0.6& 0.5&0.2 \\ \end{bmatrix} \cdot \begin{bmatrix} 0.761\\ 0.603\\ 0.650\end{bmatrix}= \begin{bmatrix} 0.975\\ 0.888\\ \end{bmatrix}\]
現在,更新示意圖展示我們的進展,從初始輸入信號開始,一層層往前流動的前饋信號,最后得到了最終層的組合輸入信號。
圖5.2.4
最后一步當然是使用S函數得到最后一層的輸出,用\(O_{ouput}\)表示:
\[O_{ouput}=Sigmoid(X_{output})=Sigmoid( \begin{bmatrix} 0.975\\ 0.888\\ \end{bmatrix} )= \begin{bmatrix} 0.726\\ 0.708\\ \end{bmatrix} \]
前饋信號的流動到此為止,任務完成!通過可視化的圖形,前饋神經網絡中信號流入方向,變化等情況我們用網絡圖最后形展示出來。
圖5.2.5
毫無疑問,整個過程就是前饋的意思,信號一直向前流動,最后輸出,中間任意層沒有信號反回上一級網絡。
下一步我們會將神經網絡的輸出值與訓練樣本中的輸出值進行比較,計算出誤差,並使用這個誤差值來反向調節權重值。
2. 反向傳播的實質
上一步我們得到了前向傳播的輸出值為[0.726, 0.708],這個值與真實值[0.01,0.99]還存在一定差距,不過沒關系,反向傳播誤差會幫助我們更新權值,縮小這些誤差,讓我們來實驗一下。
2.1 計算總誤差
因為總誤差為:\(E=\sum(target-O_{output})^2=E_{1}+E_{2}=(target1-O_{output1})^2+(target2-O_{output2})^2\)
由於我們的實驗網絡有兩個輸出,因此總誤差為兩個輸出誤差之和。
第一個誤差:
\[E_{1}=(target_{1}-O_{output1})^2=(0.726-0.01)^2=0.512656 \]
第二個誤差:
\[E_{2}=(target_{2}-O_{output2})^2=(0.706-0.99)^2=0.079524 \]
總誤差:
\[E=E_{1}+E_{2}=0.512656+0.079524=0.59218 \]
2.2 隱藏層和輸出層的權重更新
對於隱藏層和輸出層之間的權重\(w_{1,1}\)來說,如果我們想知道\(w_{1,1}\)對整體誤差產生了多少影響,可以用總誤差對\(w_{1,1}\)求偏導,該偏導可以使用鏈式法則表示。
\[\frac{\partial E}{\partial w_{1,1}}=\frac{\partial E}{\partial O_{ouput1}} \cdot \frac{\partial O_{ouput1}}{\partial X_{ouput1}} \cdot \frac{\partial X_{ouput1}}{\partial w_{1,1}} \]
如圖所示的反向傳播示意圖,並結合求導表達式,可以幫助我們更清楚的了解誤差是怎么反向傳播的。
圖5.2.6
下面我們對以上求導式子中的每個小式子分別求值
1、首先是計算$\frac{\partial E}{\partial O_{ouput1}} $
\[E=(target_{1}-O_{output1})^2+(target2-O_{output2})^2 \]
\[\frac{\partial E}{\partial O_{ouput1}}=-2(target_{1}-O_{output1})+0=-2(0.01-0.726)=1.432 \]
2、再來計算\(\frac{\partial O_{ouput1}}{\partial X_{ouput1}}\)
\[O_{ouput1}=\frac{1}{1+e^{-X_{ouput1}}} \]
\[\frac{\partial O_{ouput1}}{\partial X_{ouput1}}=O_{ouput1}(1-O_{ouput1})=0.726(1-0.726)=0.198924 \]
3、最后計算\(\frac{\partial X_{ouput1}}{\partial w_{1,1}}\)
\[X_{ouput1}=w_{1,1} \cdot O_{hidden1}+w_{2,1} \cdot O_{hidden2}+w_{3,1} \cdot O_{hidden3} \]
\[\frac{\partial X_{ouput1}}{\partial w_{1,1}}=O_{hidden1}=0.761 \]
所以:
\[\frac{\partial E}{\partial w_{1,1}}=\frac{\partial E}{\partial O_{ouput1}} \cdot \frac{\partial O_{ouput1}}{\partial X_{ouput1}} \cdot \frac{\partial X_{ouput1}}{\partial w_{1,1}}=1.432 \times 0.198924 \times 0.761=0.216777826848 \]
我們取學習率\(\eta=0.5\),利用公式$${w_{1,1}}{new}=w{1,1}-\eta \frac{\partial E}{\partial w_{1,1}}$$
得到更新后的\({w_{1,1}}_{new}\)為:$${w_{1,1}}_{new}=0.3-0.5 \times 0.216777826848=0.191611086576$$
綜上所述,也可以這樣去計算\(\frac{\partial E}{\partial w_{1,1}}\):
\[\frac{\partial E}{\partial w_{1,1}}=-2(target_{1}-O_{output1}) \cdot O_{ouput1}(1-O_{ouput1}) \cdot O_{hidden1} \]
因此,改變上述式子的變量可以更新\(w_{2,1}\),\(w_{2,1}\),\(w_{1,2}\),\(w_{2,2}\),\(w_{3,2}\)等權重值。
2.3 輸入層和隱藏層的權重更新
計算輸入層和隱藏層之間的權重和上面的方法一樣,但使用誤差對權重進行求導時,該誤差應使用兩個輸出口的總誤差,而不是一個輸入口的誤差。我們仍然用圖形化的方式來展示:
圖5.2.7
如上圖所示,對於隱藏層和輸出層之間的權重\(w_{1,1}\)來說,如果我們想知道\(w_{1,1}\)對整體誤差產生了多少影響,可以用總誤差對\(w_{1,1}\)求偏導,該偏導可以使用鏈式法則表示。
\[\frac{\partial E}{\partial w_{1,1}}=\frac{\partial E}{\partial O_{hidden1}} \cdot \frac{\partial O_{hidden1}}{\partial X_{hidden1}} \cdot \frac{\partial X_{hidden1}}{\partial w_{1,1}} \]
我們還是一個一個的計算上面的式子。
1、首先計算\(\frac{\partial E}{\partial O_{hidden1}}\)
對於隱藏層的輸出,它會接受來自兩個輸出傳來的誤差,所以:
\[\frac{\partial E}{\partial O_{hidden1}}=\frac{\partial E_{1}}{\partial O_{hidden1}}+\frac{\partial E_{2}}{\partial O_{hidden1}} \]
\[\because \frac{\partial E_{1}}{\partial O_{hidden1}}=\frac{\partial E_{1}}{\partial X_{output1}} \cdot \frac{\partial X_{output1}}{\partial O_{hidden1}} \]
\[\because \frac{\partial E_{1}}{\partial X_{output1}}=\frac{\partial E_{1}}{\partial O_{output1}} \cdot \frac{\partial O_{output1}}{\partial X_{output1}}=1.437 \times 0.198924=0.285853788 \]
下面的\(w'_{j,k}\)為隱藏層和輸出層的鏈接權重
\[X_{output1}=w'_{1,1} \cdot O_{hidden1}+w'_{2,1} \cdot O_{hidden2}+w'_{3,1} \cdot O_{hidden3} \]
\[\therefore \frac{\partial X_{output1}}{\partial O_{hidden1}}=w'_{1,1}=0.3 \]
\[\therefore \frac{\partial E_{1}}{\partial O_{hidden1}}=\frac{\partial E_{1}}{\partial X_{output1}} \cdot \frac{\partial X_{output1}}{\partial O_{hidden1}}=0.285853788 \times 0.3=0.0857561364 \]
再來計算\(\frac {\partial E_{2}}{\partial O_{hidden1}}\)
\[\because \frac{\partial E_{2}}{\partial O_{hidden1}}=\frac{\partial E_{2}}{\partial X_{output2}} \cdot \frac{\partial X_{output2}}{\partial O_{hidden1}} \]
\[\because \frac{\partial E_{2}}{\partial X_{output2}}=\frac{\partial E_{2}}{\partial O_{output2}} \cdot \frac{\partial O_{output2}}{\partial X_{output2}} \]
\[\because X_{output2}=w'_{1,2} \cdot O_{hidden1}+w'_{2,2} \cdot O_{hidden2}+w'_{3,2} \cdot O_{hidden3} \]
\[\therefore \frac{\partial X_{output2}}{\partial O_{hidden1}}=w'_{1,2} \]
\[\therefore \frac{\partial E_{2}}{\partial O_{hidden1}}=\frac{\partial E_{2}}{\partial X_{output2}} \cdot \frac{\partial X_{output2}}{\partial O_{hidden1}}=-0.116599104 \times 0.2=-0.0233198208 \]
最后得到
\[\frac{\partial E}{\partial O_{hidden1}}=\frac{\partial E_{1}}{\partial O_{hidden1}}+\frac{\partial E_{2}}{\partial O_{hidden1}}=0.0857561364-0.0233198208=0.0624363156 \]
2、再計算\(\frac{\partial O_{hidden1}}{\partial X_{hidden1}}\)
\[\because O_{hidden1}=\frac{1}{1+e^{-X_{hidden1}}} \]
\[\frac{\partial O_{hidden1}}{\partial X_{hidden1}}=O_{hidden1}(1-O_{hidden1})=0.761(1-0.761)=0.181879 \]
3、最后計算\(\frac{\partial X_{hidden1}}{\partial w_{1,1}}\)
\[\because X_{hidden1}=w_{1,1} \cdot X_{1}+w_{2,1} \cdot X_{2}+w_{3,1} \cdot X_{3} \]
\[\therefore \frac{\partial X_{hidden1}}{\partial w_{1,1}}=X1=0.9 \]
\[\frac{\partial E}{\partial w_{1,1}}=\frac{\partial E}{\partial O_{hidden1}} \cdot \frac{\partial O_{hidden1}}{\partial X_{hidden1}} \cdot \frac{\partial X_{hidden1}}{\partial w_{1,1}}=0.0624363156 \times 0.181879 \times 0.9=0.01022026918051116 \]
我們取學習率\(\eta=0.5\),利用公式$${w_{1,1}}{new}=w{1,1}-\eta \frac{\partial E}{\partial w_{1,1}}$$
得到更新后的\({w_{1,1}}_{new}\)為:$${w_{1,1}}_{new}=0.9-0.5 \times 0.01022026918051116=0.191611086576=0.89488986540974442$$
同樣的方法可以更新其他權重的值。這樣我們就完成了誤差反向傳播算法的介紹,在實際訓練中我們通過這種方法不停的迭代,直到總誤差接近0為止,得到的最優權重保留下來,訓練完成。
參考文獻:
1、《Python神經網絡編程》
2、https://www.cnblogs.com/charlotte77/p/5629865.html