神經網絡的正反向傳播算法推導


1 正向傳播

1.1 淺層神經網絡

為簡單起見,先給出如下所示的簡單神經網絡:

該網絡只有一個隱藏層,隱藏層里有四個單元,並且只輸入一個樣本,該樣本表示成一個三維向量,分別為為\(x_1\)\(x_2\)\(x_3\)。網絡的輸出為一個標量,用\(\hat{y}\)表示。考慮該神經網絡解決的問題是一個二分類的問題,把網絡的輸出解釋為正樣本的概率。比方說輸入的是一張圖片(當然圖片不可能只用三維向量就可以表示,這里只是舉個例子),該神經網絡去判斷圖片里面是否有貓,則\(\hat{y}\)代表該圖片中有貓的概率。另外,為衡量這個神經網絡的分類表現,需要設置一個損失函數,針對二分類問題,最常用的損失函數是\(log-loss\)函數,該函數如下所示:

\[L(y,\hat{y}) = -y \times log(\hat{y}) - (1-y) \times log(1-\hat{y}) \tag{1} \]

上式只考慮一個樣本的情況,其中\(y\)為真實值,\(\hat{y}\)為輸出的概率。

1.1.1 單樣本的前向傳播

我們把單個輸入樣本用向量表示為:

\[\boldsymbol{x} = \left[ \begin{matrix} x_1 \\ x_2 \\ x_3 \end{matrix} \right] \tag{2} \]

那么對於隱藏層中的第一個單元,如果不考慮激活函數,則其輸出可以表示為:

\[z^{[1]}_1 = \boldsymbol{w}^{[1]^T}_1\boldsymbol{x} + b^{[1]}_1 \tag{3} \]

上式中,字母右上角的方括號中的數字代表這是神經網絡的第幾層,如果把輸入層看作是第0層的話,那么這里的隱藏層就是第一層,字母的下標代表該層的第幾個單元。\(\boldsymbol{w}^{[1]}_1\)是權重向量,即給輸入向量的每個元素一個權重,這些權重組合起來就形成了\(\boldsymbol{w}^{[1]}_1\)向量,把向量和其權重作點乘,再加上一個偏置標量\(b^{[1]}_1\),就得到了該神經元的輸出\(z^{[1]}_1\)

同理可得隱藏層剩余三個單元的輸出為:

\[z^{[1]}_2 = \boldsymbol{w}^{[1]^T}_2\boldsymbol{x} + b^{[1]}_2 \tag{4} \]

\[z^{[1]}_3 = \boldsymbol{w}^{[1]^T}_3\boldsymbol{x} + b^{[1]}_3 \tag{5} \]

\[z^{[1]}_4 = \boldsymbol{w}^{[1]^T}_4\boldsymbol{x} + b^{[1]}_4 \tag{6} \]

但是對於每一個神經單元,其輸出必須有一個非線性激活函數,否則神經網絡的輸出就是輸入向量的線性運算得到的結果,這樣會大大限制神經網絡的能力。激活函數的種類有很多種,一般來說選用激活函數要視具體的應用情況而定,這里選用最常用的\(sigmoid\)激活函數。注:在1.2節之前,所有神經層都只用\(sigmoid\)激活函數。該函數的表達式如下:

\[{\sigma}(z) = \frac{1}{1+e^{-z}} \tag{7} \]

sigmoid函數的導數和原函數的關系如下,這在具體進行計算的時候經常會用到:

\[{\sigma}^{'}(z) = {\sigma}(z)(1-\sigma(z)) \tag{8} \]

所以上面神經單元的計算結果需要再輸入到sigmoid函數進行計算:

\[a^{[1]}_1 = {\sigma}(z^{[1]}_1) \tag{9} \]

\[a^{[1]}_2 = {\sigma}(z^{[1]}_2) \tag{10} \]

\[a^{[1]}_3 = {\sigma}(z^{[1]}_3) \tag{11} \]

\[a^{[1]}_4 = {\sigma}(z^{[1]}_4) \tag{12} \]

上面的四個式子中,上下角標的意義不變,用字母\(a\)來表示激活函數的輸出結果是因為單詞activation(激活)的首字母為a。
至此已經完成了從輸入向量到隱藏層的輸出計算,現在再計算最后一步,即從隱藏層到最終的輸出。

和上述的計算過程一樣,只不過這次是把隱藏層的輸出作為輸出層的輸入,先把\(a^{[1]}_1\)\(a^{[1]}_4\)組成一個向量:

\[\boldsymbol{a^{[1]}} = \left[ \begin{matrix} a^{[1]}_1 \\ a^{[1]}_2 \\ a^{[1]}_3 \\ a^{[1]}_4 \end{matrix} \right] \tag{13} \]

再把該向量和對應的權重向量作點乘,最后加上一個偏置標量:

\[z^{[2]}_1 = \boldsymbol{w}^{[2]^T}_1\boldsymbol{a^{[1]}} + b^{[2]}_1 \tag{14} \]

輸出層是隱藏層的下一層,所以方括號的標注變成了2;由於輸出只有一個神經單元,所以上式可省略下標:

\[z^{[2]} = \boldsymbol{w}^{[2]^T}\boldsymbol{a^{[1]}} + b^{[2]} \tag{15} \]

同樣地,把上面的結果輸入到\(sigmoid\)函數里面,得到最終的輸出結果:

\[\hat{y} = a^{[2]} = {\sigma}(z^{[2]}) \tag{16} \]

單樣本在神經網絡的前向傳播計算到這里基本已經結束了,但是上面的計算過程顯得不是那么緊湊,比如在計算隱藏層的第一到第四個神經單元輸出結果的時候,我們是按順序一個一個計算的,這樣的計算如果在具有非常多的神經單元的情況下,會導致最終的計算速度很慢,不高效。所以我們應當把上述的計算過程向量化,不僅使得公式更加簡潔明了,而且會大大加快運算速度(很多軟件包針對向量計算做了優化)。向量化的過程敘述如下:

首先考慮隱藏層中的權重向量,這些向量可以按行整合成一個矩陣:

\[\boldsymbol{W^{[1]}} = \left[ \begin{matrix} ...\boldsymbol{w}^{[1]^T}_1 ...\\ ...\boldsymbol{w}^{[1]^T}_2 ...\\ ...\boldsymbol{w}^{[1]^T}_3 ...\\ ...\boldsymbol{w}^{[1]^T}_4 ... \end{matrix} \right] \tag{17} \]

同樣地,標量\(b^{[1]}_1\)\(b^{[1]}_4\), \(z^{[1]}_1\)\(z^{[1]}_4\)以及\(a^{[1]}_1\)\(a^{[1]}_4\)可以分別組成一個列向量:

\[\boldsymbol{b^{[1]}} = \left[ \begin{matrix} b^{[1]}_1\\ b^{[1]}_2 \\ b^{[1]}_3 \\ b^{[1]}_4 \end{matrix} \right] \tag{18} \]

\[\boldsymbol{z^{[1]}} = \left[ \begin{matrix} z^{[1]}_1\\ z^{[1]}_2 \\ z^{[1]}_3 \\ z^{[1]}_4 \end{matrix} \right] \tag{19} \]

\[\boldsymbol{a^{[1]}} = \left[ \begin{matrix} a^{[1]}_1\\ a^{[1]}_2 \\ a^{[1]}_3 \\ a^{[1]}_4 \end{matrix} \right] \tag{20} \]

這樣,式(3)-式(6)可以用向量形式表達為:

\[\boldsymbol{z^{[1]}} = \boldsymbol{W^{[1]}}\boldsymbol{x} + \boldsymbol{b^{[1]}} \tag{21} \]

其中\(\boldsymbol{W^{[1]}}\)是一個\(4\times3\)的矩陣,\(\boldsymbol{x}\)向量為\(3\times1\),二者相乘得到的維數為\(4\times1\),剛好和\(\boldsymbol{b^{[1]}}\)\(\boldsymbol{z^{[1]}}\)的維數相同。

然后計算\(\boldsymbol{a^{[1]}}\):

\[\boldsymbol{a^{[1]}} = {\sigma}(\boldsymbol{z^{[1]}}) \tag{22} \]

\({\sigma}(\boldsymbol{z^{[1]}})\)的計算方式是,對向量\(\boldsymbol{z^{[1]}}\)中的每一個元素,依次輸入到\(sigmoid\)函數中計算,最后將結果整合成一個向量。

同樣可以把輸出層的計算過程用向量表示:

\[\boldsymbol{z^{[2]}} = \boldsymbol{W^{[2]}}\boldsymbol{\boldsymbol{a^{[1]}}} + \boldsymbol{b^{[2]}} \tag{23} \]

\[\boldsymbol{a^{[2]}} = {\sigma}(\boldsymbol{z^{[2]}}) \tag{24} \]

其中\(\boldsymbol{W^{[2]}}\)是一個\(1\times4\)的矩陣,\(\boldsymbol{a^{[1]}}\)向量為\(4\times1\),二者相乘得到的維數為\(1\times1\)\(\boldsymbol{b^{[2]}}\)也是一個標量,所以最后的結果肯定是一個標量,也就是\(\boldsymbol{a^{[2]}}\)了,這里將\(\boldsymbol{a^{[2]}}\)\(\boldsymbol{b^{[2]}}\)加粗是為了和向量表示相統一,實際上它並不是一個向量,除非輸出的數值不止一個。

從上面的計算過程也可以總結出,權重矩陣\(\boldsymbol{W^{[l]}}\)的維數是\(n^{[l]}\times n^{[l-1]}\),偏置向量\(\boldsymbol{b^{[l]}}\)的維數是\(n^{[l]}\times 1\),其中\(l\)代表某一層,\(l-1\)則為上一層,\(n^{[l]}\)代表該層的神經單元數。

綜上所述,式(21)-式(24)用向量化的方式完成了單樣本輸入神經網絡的計算,總共就四個表達式,看起來十分簡潔。

1.1.2 多樣本的前向傳播

在上面的例子中,我們使用的是單樣本的前向傳播過程,實際應用中是不可能只有一個樣本的,會有很多個樣本,那么針對多樣本的前向傳播過程又是怎么樣的呢?其實過程是和單樣本的過程是一樣的,只不過是把輸入的單個向量\(\boldsymbol{x}\)變成了矩陣\(\boldsymbol{X}\),該矩陣是把輸入的每一個樣本向量按排序得到的,下面考慮m個樣本,式(25)中右上角的圓括號中的數字代表樣本編號:

\[\boldsymbol{X} = \left[ \begin{matrix} \vdots & \vdots & & \vdots \\ \boldsymbol{x^{(1)}} & \boldsymbol{x^{(2)}} & \cdots & \boldsymbol{x^{(m)}} \\ \vdots & \vdots & & \vdots \end{matrix} \right] \tag{25} \]

那么式(21)-式(24)拓展到m個樣本,就可以改寫為:

\[\boldsymbol{Z^{[1]}} = \boldsymbol{W^{[1]}}\boldsymbol{X} + \boldsymbol{B^{[1]}} \tag{26} \]

\[\boldsymbol{A^{[1]}} = {\sigma}(\boldsymbol{Z^{[1]}}) \tag{27} \]

\[\boldsymbol{Z^{[2]}} = \boldsymbol{W^{[2]}}\boldsymbol{\boldsymbol{A^{[1]}}} + \boldsymbol{B^{[2]}} \tag{28} \]

\[\boldsymbol{A^{[2]}} = {\sigma}(\boldsymbol{Z^{[2]}}) \tag{29} \]

式(26)-式(29)相對於式(21)-式(24)唯一的變化就是把z、a和b由向量表示轉變為矩陣表示,具體的來看,比方說\(\boldsymbol{Z^{[1]}}\)\(\boldsymbol{B^{[1]}}\)\(\boldsymbol{A^{[1]}}\)可類似於\(\boldsymbol{X}\)展開為:

\[\boldsymbol{Z^{[1]}} = \left[ \begin{matrix} \vdots & \vdots & & \vdots \\ \boldsymbol{z^{(1)^{[1]}}} & \boldsymbol{z^{(2)^{[1]}}} & \cdots & \boldsymbol{z^{(m)^{[1]}}} \\ \vdots & \vdots & & \vdots \end{matrix} \right] \tag{30} \]

\[\boldsymbol{B^{[1]}} = \left[ \begin{matrix} \vdots & \vdots & & \vdots \\ \boldsymbol{b^{(1)^{[1]}}} & \boldsymbol{b^{(2)^{[1]}}} & \cdots & \boldsymbol{b^{(m)^{[1]}}} \\ \vdots & \vdots & & \vdots \end{matrix} \right] \tag{31} \]

\[\boldsymbol{A^{[1]}} = \left[ \begin{matrix} \vdots & \vdots & & \vdots \\ \boldsymbol{a^{(1)^{[1]}}} & \boldsymbol{a^{(2)^{[1]}}} & \cdots & \boldsymbol{a^{(m)^{[1]}}} \\ \vdots & \vdots & & \vdots \end{matrix} \right] \tag{32} \]

如果覺得矩陣表示較為抽象,就可以應用這種展開方式方便理解。另外要注意,對於上面的矩陣\(\boldsymbol{B^{[1]}}\),其中的各個列向量\(\boldsymbol{b^{(1)^{[1]}}}\)\(\boldsymbol{b^{(2)^{[1]}}}\)等等,其實是完全一樣的,就是同一個列向量重復地排了\(m\)列,正如權重矩陣\(\boldsymbol{W^{[l]}}\)不會隨着樣本的個數變化一樣,偏置向量也是不會隨着樣本的不同而不同的。總而言之,對於同一個神經層,權重矩陣和偏置向量對於所有樣本相同。從中可見式(26)-式(29)的維數也是正確的,例如式(26)中,\(\boldsymbol{W^{[1]}}\)維數是\(4\times3\),\(\boldsymbol{X}\)的維數是\(3\times m\),二者相乘的維數是\(4\times m\),而\(\boldsymbol{B^{[1]}}\)以及\(\boldsymbol{Z^{[1]}}\)的維數均是\(4\times m\),所以式(26)在維度上完全正確,余下的幾個式子的維數分析同理。最后輸出的是m個樣本的計算結果:\(\boldsymbol{A^{[2]}}\),它是把每個樣本單獨輸出的結果按排列得到,這和之前所有樣本均按排列的方式是一致的。至此也完成了m個樣本在淺層神經網絡的正向傳播過程。

1.2 深層神經網絡

利用淺層神經網絡的分析結果,我們很容易把正向傳播過程推廣到深層神經網絡上,即不再像本文開始提出的那種只有一個隱藏層並且只有4個隱藏神經單元的神經網絡,可以有很多個隱藏層,每個隱藏層也可以有很多個神經單元,也不再限定輸入的是一個三維向量,輸入的可以為任意維向量,當然,每個樣本的向量維度必須一致,否則神經網絡沒法工作,同時網絡的輸出也可不限定為一個數值,可以輸出一個向量以適應多分類的任務,即一個樣本會有多個標簽,輸出向量表示該樣本屬於這些標簽的概率值。最后作為一般概括,也不指定具體的激活函數,即激活函數在這里用\(g^{[l]}(x)\)表示。這樣,我們可以把整個正向傳輸過程濃縮成:

\[\boldsymbol{Z^{[l]}} = \boldsymbol{W^{[l]}}\boldsymbol{A^{[l-1]}} + \boldsymbol{b^{[l]}} \tag{33} \]

\[\boldsymbol{A^{[l]}} = g^{[l]}(\boldsymbol{Z^{[l]}}) \tag{34} \]

上式中某一層用\(l\)表示,它的上一層用\(l-1\)來表示,這里規定輸入層\(l=0\),第一個隱藏層\(l=1\),后面以此類推,即有\(1 \leq l \leq N\),\(N\)為輸出層編號。所以上面兩個式子的計算過程就是輸入上一層計算的\(\boldsymbol{A^{[l-1]}}\),再輸出本層的\(\boldsymbol{A^{[l]}}\),一直持續計算到輸出層,最后得到計算的最終結果。需要注意的一點是對於第一個隱藏層,它的輸入就是樣本矩陣,也就是\(\boldsymbol{A^{[0]}} = \boldsymbol{X}\)注意到式(33)我們沒有用大寫的\(\boldsymbol{B^{[l]}}\)來代表偏置矩陣,而是用了小寫的向量記法,代表的是一個列向量,這是為了后續反向傳播推導的方便,但是我們心里應該明白,這里一個矩陣和一個向量相加,相加的方法是矩陣的每一列分別和該列向量相加,這樣就和原大寫的矩陣相加結果相同,因為前面已經指出,矩陣\(\boldsymbol{B^{[l]}}\)就是單個列向量擴展\(m\)列得到的。

最后再來總結式(33)-式(34)中每個元素的維數,根據淺層神經網絡的推導,我們也很容易把結論擴展到深層神經網絡里面。以\(n^{[l]}\)表示該層的神經單元的個數(輸入層\(n^{[0]}\)等於輸入樣本矩陣的行數,即單個樣本向量的元素個數),m表示樣本個數,則結論如下:

\[\boldsymbol{W^{[l]}} \in \mathbb{R}^{n^{[l]} \times n^{[l-1]}} \tag{35} \]

\[\boldsymbol{b^{[l]}} \in \mathbb{R}^{n^{[l]} \times 1} \tag{36} \]

\[\boldsymbol{Z^{[l]}} \in \mathbb{R}^{n^{[l]} \times m} \tag{37} \]

\[\boldsymbol{A^{[l]}} \in \mathbb{R}^{n^{[l]} \times m} \tag{38} \]

2 反向傳播

現在來考慮反向傳播的過程,該過程是一個不斷迭代的過程,目的是尋找使得損失函數最小的參數,即每一個神經層的權重矩陣和偏置向量的數值。首先考慮單個樣本在深層神經網絡的反向傳播的情況。

2.1 單樣本的反向傳播

計算反向傳播的過程,我們首先要定義一個損失函數,為了不失一般性,這里用\(L(\boldsymbol{y}, \boldsymbol{\hat y})\)表示損失函數,其中\(\boldsymbol{y}\)為樣本的真實標簽,\(\boldsymbol{\hat y}\)為樣本在神經網絡中的計算結果。損失函數應當越小越好,越小就代表我們計算出的結果和樣本的真實標簽越接近。為和前面的章節相連貫,接下來我們考慮的是作為分類任務用的神經網絡,即每一層包括輸出層都會有一個激活函數,注意如果是回歸任務,輸出層是不需要激活函數的,因為激活函數會把輸出結果限定在一個范圍內,這對回歸任務並不適用。我們記作\(g(x)^{[l]}\),\(l\)代表某一層。

針對單個樣本,可記作:

\[\boldsymbol{a^{[0]}} = \boldsymbol{x} = \left[ \begin{matrix} x_1 \\ x_2 \\ \vdots \\ x_{n^{[0]}} \end{matrix} \right] \tag{39} \]

\(n^{[l]}\)表示\(l\)層的神經單元的個數,輸入層的\(l\)記作0。那么后面的計算就可利用下面兩個式子反復進行,其中\(1\leq l \leq N\),N為輸出層編號。一直進行到輸出層得出結果:

\[\boldsymbol{z^{[l]}} = \boldsymbol{W^{[l]}}\boldsymbol{a^{[l-1]}} + \boldsymbol{b^{[l]}} \tag{40} \]

\[\boldsymbol{a^{[l]}} = g^{[l]}(\boldsymbol{z^{[l]}}) \tag{41} \]

假設神經網絡一共有N層,我們則把最后的輸出結果記作\(\boldsymbol{a^{[N]}}\),也就是\(\boldsymbol{\hat{y}}\)。利用損失函數最終得到損失值,我們的任務就是最小化這個數值,如何最小化?那么就必須調節參數\(\boldsymbol{W^{[l]}}\)\(\boldsymbol{b^{[l]}}\),這時候就需要用到反向傳播算法了,即正向傳播計算的是神經網絡的輸出值,而反向傳播則計算修改后的網絡參數,不斷地進行正向反向傳播,每一個正反來回都對這兩個參數進行更新,再計算神經網絡在參數更新后的損失值,和原來的損失值作比較,變小了就繼續進行參數更新,反之則考慮是否停止參數更新,結束神經網絡的計算。參數更新的過程如下所示,其中\(1\leq l\leq N\)

\[\boldsymbol{W^{[l]}} = \boldsymbol{W^{[l]}} - \alpha \times d\boldsymbol{W^{[l]}} \tag{42} \]

\[\boldsymbol{b^{[l]}} = \boldsymbol{b^{[l]}} - \alpha \times d\boldsymbol{b^{[l]}} \tag{43} \]

式中,\(d\boldsymbol{W^{[l]}}\)\(d\boldsymbol{b^{[l]}}\)分別代表損失函數對這二者的求偏導的結果,即:

\[d{\boldsymbol{W^{[l]}}} = \frac{\partial L}{\partial{\boldsymbol{W^{[l]}}}} \tag{44} \]

\[d{\boldsymbol{b^{[l]}}} = \frac{\partial L}{\partial{\boldsymbol{b^{[l]}}}} \tag{45} \]

\(\alpha\)代表參數更新的步長,稱作學習率。問題的關鍵就在於怎么求出\(d\boldsymbol{W^{[l]}}\)\(d\boldsymbol{b^{[l]}}\),這時候就需要考慮導數的鏈式法則了。反向傳播的起點在最后一步,即損失函數這一步,從輸出層開始再一層一層地往回計算,所以先考慮損失函數\(L(\boldsymbol{a^{[N]}} \boldsymbol{\hat y})\)和輸出層參數,即先計算出\(d\boldsymbol{W^{[N]}}\)\(d\boldsymbol{b^{[N]}}\),先考慮前者,根據鏈式法則,很容易得出下式:

\[\begin{align*} d{\boldsymbol{W^{[N]}}} &= \frac{\partial L}{\partial{\boldsymbol{W^{[N]}}}} \\ &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{W^{[N]}}}} \\ &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}} \frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{W^{[N]}}}} \end{align*} \tag{46} \]

可見計算\(d{\boldsymbol{W^{[N]}}}\)共需三步,即分別計算\(\frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}}\),\(\frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}}\)\(\frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{W^{[N]}}}}\),然后相乘即可。
首先\(\boldsymbol{a^{[N]}}\)求偏導得到:

\[d{\boldsymbol{a^{[N]}}} = \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \tag{47} \]

式(47)的具體計算結果依賴於具體的損失函數L,由於我們作一般化考慮,所以到此為止,不再繼續計算下去。然后根據式(41)又有:

\[\frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}} = {g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \tag{48} \]

再根據式(40),得到:

\[\frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{W^{[N]}}}} = \boldsymbol{a^{[N-1]}} \tag{49} \]

綜合式(47)-式(48),可以得到:

\[\begin{align*} d{\boldsymbol{z^{[N]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}}\frac{\partial{\boldsymbol{a^{[N]}}}} {\partial{\boldsymbol{z^{[N]}}}} \\ &= d{\boldsymbol{a^{[N]}}}{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \end{align*} \tag{50} \]

但是要注意的是,式(50)並不正確,因為維度不匹配。各元素維度為:

\[d{\boldsymbol{z^{[N]}}} \in \mathbb{R}^{n[N]\times 1} \tag{51} \]

\[d{\boldsymbol{a^{[N]}}} \in \mathbb{R}^{n[N]\times 1} \tag{52} \]

\[{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \in \mathbb{R}^{n[N]\times 1} \tag{53} \]

所以改寫式(50)使其滿足正確的維度:

\[\begin{align*} d{\boldsymbol{z^{[N]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}}\frac{\partial{\boldsymbol{a^{[N]}}}} {\partial{\boldsymbol{z^{[N]}}}} \\ &= d{\boldsymbol{a^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \end{align*} \tag{54} \]

式(54)中的空心圓點代表這兩個向量對應元素進行相乘。再把式(54)和式(49)聯立,可得:

\[d{\boldsymbol{W^{[N]}}} = d{\boldsymbol{z^{[N]}}}\boldsymbol{a^{[N-1]}} \tag{55} \]

同樣地,式(55)也不滿足正確的維度。各元素的維度為:

\[d{\boldsymbol{z^{[N]}}} \in \mathbb{R}^{n[N]\times 1} \tag{56} \]

\[\boldsymbol{a^{[N-1]}} \in \mathbb{R}^{n[N]\times 1} \tag{57} \]

\[d{\boldsymbol{W^{[N]}}} \in \mathbb{R}^{n[N]\times n[N-1]} \tag{58} \]

改寫式(55)使其滿足正確的維度:

\[d{\boldsymbol{W^{[N]}}} = d{\boldsymbol{z^{[N]}}}\boldsymbol{{a^{[N-1]}}^T} \tag{59} \]

至此已經完成了\(d{\boldsymbol{W^{[N]}}}\)的計算,那么還剩下\(d{\boldsymbol{b^{[N]}}}\)還沒有計算,計算它就簡單多了,因為根據式(40),\(d{\boldsymbol{b^{[N]}}}\)就等於\(d{\boldsymbol{z^{[N]}}}\),所以有:

\[\begin{align*} d{\boldsymbol{b^{[N]}}} &= d{\boldsymbol{z^{[N]}}} \\ &= d{\boldsymbol{a^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \end{align*} \tag{60} \]

\(d{\boldsymbol{W^{[N]}}}\)\(d{\boldsymbol{b^{[N]}}}\)都計算出來之后,就可以利用式(42)-式(43)更新參數了:

\[\boldsymbol{W^{[N]}} = \boldsymbol{W^{[N]}} - \alpha \times d\boldsymbol{W^{[N]}} \tag{61} \]

\[\boldsymbol{b^{[N]}} = \boldsymbol{b^{[N]}} - \alpha \times d\boldsymbol{b^{[N]}} \tag{62} \]

下面再來考慮\(d{\boldsymbol{W^{[N-1]}}}\)\(d{\boldsymbol{b^{[N-1]}}}\)的計算,即輸出層的上一層,也就是最后一個隱藏層的參數。事實上,根據式(59)-式(60),就可以進行計算了,不過是把N換成N-1而已,但是這里有個問題是\(d{\boldsymbol{a^{[N-1]}}}\)沒法得出,所以關鍵就是把它的表達式給求出來。根據式(40)-式(41),再應用鏈式法則,不難得到:

\[\begin{align*} d{\boldsymbol{a^{[N-1]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N-1]}}}} \\ &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}} \frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{a^{[N-1]}}}} \end{align*} \tag{63} \]

式(63)可整理如下:

\[\begin{align*} d{\boldsymbol{a^{[N-1]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}} \frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{a^{[N-1]}}}} \\ &= d{\boldsymbol{z^{[N]}}}{\boldsymbol{W^{[N]}}} \end{align*} \tag{64} \]

式(64)的維度也是有問題的,整理如下,使得元素維度匹配:

\[\begin{align*} d{\boldsymbol{a^{[N-1]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \frac{\partial{\boldsymbol{a^{[N]}}}}{\partial{\boldsymbol{z^{[N]}}}} \frac{\partial{\boldsymbol{z^{[N]}}}}{\partial{\boldsymbol{a^{[N-1]}}}} \\ &= {\boldsymbol{W^{[N]}}}^Td{\boldsymbol{z^{[N]}}} \end{align*} \tag{65} \]

目前為止,基本完成了單個樣本的反向傳播過程,主要過程、公式整理如下:

對於輸出層有:

\[d{\boldsymbol{a^{[N]}}} = \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}} \tag{66} \]

\[\begin{align*} d{\boldsymbol{z^{[N]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[N]}}}}\frac{\partial{\boldsymbol{a^{[N]}}}} {\partial{\boldsymbol{z^{[N]}}}} \\ &= d{\boldsymbol{a^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \end{align*} \tag{67} \]

\[d{\boldsymbol{W^{[N]}}} = d{\boldsymbol{z^{[N]}}}\boldsymbol{{a^{[N-1]}}^T} \tag{68} \]

\[\begin{align*} d{\boldsymbol{b^{[N]}}} &= d{\boldsymbol{z^{[N]}}} \\ &= d{\boldsymbol{a^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{z^{[N]}}) \end{align*} \tag{69} \]

其中\(d{\boldsymbol{a^{[N]}}}\)是可以直接利用損失函數進行求導計算得出,而對於其他神經層則需要利用鏈式法則來求出。設\(h\)為為任意隱藏層,即\(1\leq h \leq N-1\),則有:

\[\begin{align*} d{\boldsymbol{a^{[h]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[h+1]}}}} \frac{\partial{\boldsymbol{a^{[h+1]}}}}{\partial{\boldsymbol{z^{[h+1]}}}} \frac{\partial{\boldsymbol{z^{[h+1]}}}}{\partial{\boldsymbol{a^{[h]}}}} \\ &= {\boldsymbol{W^{[h+1]}}}^Td{\boldsymbol{z^{[h+1]}}} \end{align*} \tag{70} \]

\[\begin{align*} d{\boldsymbol{z^{[h]}}} &= \frac{\partial L}{\partial{\boldsymbol{a^{[h]}}}}\frac{\partial{\boldsymbol{a^{[h]}}}} {\partial{\boldsymbol{z^{[h]}}}} \\ &= d{\boldsymbol{a^{[h]}}}\circ{g^{[h]}}^{\prime}(\boldsymbol{z^{[h]}}) \end{align*} \tag{71} \]

\[d{\boldsymbol{W^{[h]}}} = d{\boldsymbol{z^{[h]}}}\boldsymbol{{a^{[h-1]}}^T} \tag{72} \]

\[\begin{align*} d{\boldsymbol{b^{[h]}}} &= d{\boldsymbol{z^{[h]}}} \\ &= d{\boldsymbol{a^{[h]}}}\circ{g^{[h]}}^{\prime}(\boldsymbol{z^{[h]}}) \end{align*} \tag{73} \]

最后的參數更新只需按照下面式子來進行即可,其中\(1 \leq l \leq N\)

\[\boldsymbol{W^{[l]}} = \boldsymbol{W^{[l]}} - \alpha \times d\boldsymbol{W^{[l]}} \tag{74} \]

\[\boldsymbol{b^{[l]}} = \boldsymbol{b^{[l]}} - \alpha \times d\boldsymbol{b^{[l]}} \tag{75} \]

2.2 多樣本的反向傳播

考慮\(m\)個樣本,各種符號表示以及解釋參考式(25)-式(32)。損失函數則定義為所有樣本損失值的平均值,即有如下定義:

\[J(\boldsymbol{W}, \boldsymbol{b}) = \frac{1}{m}\Sigma^{m}_{i=1}L(\boldsymbol{y^{(i)}}, \boldsymbol{\hat y^{(i)}}) \tag{76} \]

總的損失函數值是所有樣本的損失值的平均,那么權值參數\(\boldsymbol{W^{[l]}}\)和偏置參數\(\boldsymbol{b^{[l]}}\)也應當是考慮了所有的樣本計算后的平均。同樣地,先考慮輸出層的參數,利用式(66)-式(69)可得:

\[d{\boldsymbol{A^{[N]}}} = \frac{\partial J}{\partial{\boldsymbol{A^{[N]}}}} \tag{77} \]

\[\begin{align*} d{\boldsymbol{Z^{[N]}}} &= \frac{\partial J}{\partial{\boldsymbol{A^{[N]}}}}\frac{\partial{\boldsymbol{A^{[N]}}}} {\partial{\boldsymbol{z^{[N]}}}} \\ &= d{\boldsymbol{A^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{Z^{[N]}}) \end{align*} \tag{78} \]

\[d{\boldsymbol{W^{[N]}}} = \frac{1}{m}d{\boldsymbol{Z^{[N]}}}\boldsymbol{{A^{[N-1]}}^T} \tag{79} \]

\[\begin{align*} d{\boldsymbol{b^{[N]}}} &= \frac{1}{m}sum(d{\boldsymbol{Z^{[N]}}},axis=1) \\ &= \frac{1}{m}sum(d{\boldsymbol{A^{[N]}}}\circ{g^{[N]}}^{\prime}(\boldsymbol{Z^{[N]}}), axis=1) \end{align*} \tag{80} \]

注意的是式(80),列向量\(d{\boldsymbol{b^{[N]}}}\)是通過\(d{\boldsymbol{Z^{[N]}}}\)矩陣取每一行的平均值得到的,在直覺上也不難理解,矩陣\(d{\boldsymbol{Z^{[N]}}}\)是每個樣本的\(d{\boldsymbol{z^{[N]}}}\)按列排列得到的,而\(d{\boldsymbol{b^{[N]}}}\)需要對每個樣本的\(d{\boldsymbol{b^{[N]}}}\)求平均而得到,式(80)的做法正符合這一要求。至於式(78)只要將矩陣相乘的結果除以樣本個數,這種做法可以將兩個矩陣拆開來看,可以發現\(d{\boldsymbol{W^{[N]}}}\)確實也是綜合考慮了所有樣本的\(d{\boldsymbol{W^{[N]}}}\),然后求平均得到,具體請自行操作體會。

對於所有隱藏層,對式(70)-式(73)進行同樣的改動,即可獲得相應結果。設\(h\)為為任意隱藏層,即\(1\leq h \leq N-1\),則有:

\[\begin{align*} d{\boldsymbol{A^{[h]}}} &= \frac{\partial J}{\partial{\boldsymbol{A^{[h+1]}}}} \frac{\partial{\boldsymbol{A^{[h+1]}}}}{\partial{\boldsymbol{Z^{[h+1]}}}} \frac{\partial{\boldsymbol{Z^{[h+1]}}}}{\partial{\boldsymbol{A^{[h]}}}} \\ &= {\boldsymbol{W^{[h+1]}}}^Td{\boldsymbol{Z^{[h+1]}}} \end{align*} \tag{81} \]

\[\begin{align*} d{\boldsymbol{Z^{[h]}}} &= \frac{\partial J}{\partial{\boldsymbol{A^{[h]}}}}\frac{\partial{\boldsymbol{A^{[h]}}}} {\partial{\boldsymbol{Z^{[h]}}}} \\ &= d{\boldsymbol{A^{[h]}}}\circ{g^{[h]}}^{\prime}(\boldsymbol{Z^{[h]}}) \end{align*} \tag{82} \]

\[d{\boldsymbol{W^{[h]}}} = \frac{1}{m}d{\boldsymbol{Z^{[h]}}}\boldsymbol{{A^{[h-1]}}^T} \tag{83} \]

\[\begin{align*} d{\boldsymbol{b^{[h]}}} &= \frac{1}{m}sum(d{\boldsymbol{Z^{[h]}}}, axis=1) \\ &= \frac{1}{m}sum(d{\boldsymbol{A^{[h]}}}\circ{g^{[h]}}^{\prime}(\boldsymbol{Z^{[h]}}), axis=1) \end{align*} \tag{84} \]

更新參數的方法同式(74)-式(75)。順便提一下,在實際應用中,往往會在式(76)所示的損失函數后面加上一個正則化項,以防止過擬合。現在我們使用下式所示的損失函數:

\[J(\boldsymbol{W}, \boldsymbol{b}) = \frac{1}{m}\Sigma^{m}_{i=1}L(\boldsymbol{y^{(i)}}, \boldsymbol{\hat y^{(i)}}) + \frac{\lambda}{2m}\Sigma^{l}_{l=1}||\boldsymbol{W^{[l]}}||^2_F \tag{85} \]

其中:

\[||\boldsymbol{W^{[l]}}||^2_F = \Sigma^{n[l]}_{i=1}\Sigma^{n[l-1]}_{j=1}(\boldsymbol{W^{[l]}_{ij}})^2 \tag{86} \]

即矩陣中每個元素的平方之和。這種矩陣范數稱為Frobenius范數。正則化項中的\(\lambda\)是正則化參數,這是一個超參數,需要在實驗中進行調節,不斷地嘗試才能確定最好的\(\lambda\)值。對於包含這種正則化項的反向傳播又作如何處理?其實就是在\(d{\boldsymbol{W}}\)的后面加上\(\frac{\lambda}{m}\boldsymbol{W}\)即可,而\(d{\boldsymbol{b}}\)參數不需要變化。式(79)和式(83)可分別改寫為:

\[d{\boldsymbol{W^{[N]}}} = \frac{1}{m}d{\boldsymbol{Z^{[N]}}}\boldsymbol{{A^{[N-1]}}^T}+\frac{\lambda}{m}\boldsymbol{W^{[N]}} \tag{87} \]

\[d{\boldsymbol{W^{[h]}}} = \frac{1}{m}d{\boldsymbol{Z^{[h]}}}\boldsymbol{{A^{[h-1]}}^T}+\frac{\lambda}{m}\boldsymbol{W^{[h]}} \tag{88} \]

再利用式(74)-式(75)進行參數更新即可,可見加了正則化項之后,參數會比原來要小一點,因為多減去了\(\frac{\lambda}{m}\boldsymbol{W}\)這一項。現在,神經網絡的正反向傳播算法基本推導完畢。

參考文獻
吳恩達《深度學習》視頻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM