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}\)這一項。現在,神經網絡的正反向傳播算法基本推導完畢。
參考文獻
吳恩達《深度學習》視頻