神經(jīng)網(wǎng)絡(luò)之反向傳播算法(BP)詳細(xì)公式推導(dǎo)

反向傳播算法詳細(xì)推導(dǎo)

反向傳播(英語(yǔ):Backpropagation,縮寫為BP)是“誤差反向傳播”的簡(jiǎn)稱,是一種與最優(yōu)化方法(如梯度下降法)結(jié)合使用的,用來(lái)訓(xùn)練人工神經(jīng)網(wǎng)絡(luò)的常見方法。該方法對(duì)網(wǎng)絡(luò)中所有權(quán)重計(jì)算損失函數(shù)的梯度。這個(gè)梯度會(huì)反饋給最優(yōu)化方法,用來(lái)更新權(quán)值以最小化損失函數(shù)。 在神經(jīng)網(wǎng)絡(luò)上執(zhí)行梯度下降法的主要算法。該算法會(huì)先按前向傳播方式計(jì)算(并緩存)每個(gè)節(jié)點(diǎn)的輸出值,然后再按反向傳播遍歷圖的方式計(jì)算損失函數(shù)值相對(duì)于每個(gè)參數(shù)的偏導(dǎo)數(shù)。

我們將以全連接層,激活函數(shù)采用 Sigmoid 函數(shù),誤差函數(shù)為 Softmax+MSE 損失函數(shù)的神經(jīng)網(wǎng)絡(luò)為例,推導(dǎo)其梯度傳播方式。

準(zhǔn)備工作

1、Sigmoid 函數(shù)的導(dǎo)數(shù)

回顧 sigmoid 函數(shù)的表達(dá)式:
\sigma(x) = \frac{1}{1+e^{-x}}
其導(dǎo)數(shù)為:
\fracu0z1t8os{dx}\sigma(x) = \fracu0z1t8os{dx} \left(\frac{1}{1+e^{-x}} \right)

= \frac{e^{-x}}{(1+e^{-x})^2}

= \frac{(1 + e^{-x})-1}{(1+e^{-x})^2}

=\frac{1+e^{-x}}{(1+e^{-x})^2} - \left(\frac{1}{1+e^{-x}}\right)^2

= \sigma(x) - \sigma(x)^2

= \sigma(1-\sigma)

可以看到,Sigmoid 函數(shù)的導(dǎo)數(shù)表達(dá)式最終可以表達(dá)為激活函數(shù)的輸出值的簡(jiǎn)單運(yùn)算,利
用這一性質(zhì),在神經(jīng)網(wǎng)絡(luò)的梯度計(jì)算中,通過緩存每層的 Sigmoid 函數(shù)輸出值,即可在需
要的時(shí)候計(jì)算出其導(dǎo)數(shù)。Sigmoid 函數(shù)導(dǎo)數(shù)的實(shí)現(xiàn):

import numpy as np # 導(dǎo)入 numpy

def sigmoid(x): # sigmoid 函數(shù)
    return 1 / (1 + np.exp(-x))

def derivative(x): # sigmoid 導(dǎo)數(shù)的計(jì)算
    return sigmoid(x)*(1-sigmoid(x))

2、均方差函數(shù)梯度

均方差損失函數(shù)表達(dá)式為:
L = \frac{1}{2}\sum_{k=1}^{K}(y_k-o_k)^2
其中y_k為真實(shí)值,o_k為輸出值。則它的偏導(dǎo)數(shù)\frac{\partial L}{\partial o_i} 可以展開為:
\frac{\partial L}{\partial o_i} = \frac{1}{2}\sum_{k=1}^{K}\frac{\partial}{\partial o_i}(y_k - o_k)^2
利用鏈?zhǔn)椒▌t分解為
\frac{\partial L}{\partial o_i} = \frac{1}{2}\sum_{k=1}^{K}\cdot2\cdot(y_k-o_k)\cdot\frac{\partial(y_k-o_k)}{\partial o_i}

\frac{\partial L}{\partial o_i} = \sum_{k=1}^{K}(y_k-o_k)\cdot(-1)\cdot\frac{\partial o_k}{\partial o_i}

\frac{\partial o_k}{\partial o_i}僅當(dāng) k = i 時(shí)才為 1,其他點(diǎn)都為0, 也就是說 \frac{\partial o_k}{\partial o_i}只與第 i號(hào)節(jié)點(diǎn)相關(guān),與其他節(jié)點(diǎn)無(wú)關(guān),因此上式中的求和符號(hào)可以去掉,均方差的導(dǎo)數(shù)可以推導(dǎo)為
\frac{\partial L}{\partial o_i} = (o_i - y_i)

單個(gè)神經(jīng)元梯度

對(duì)于采用 Sigmoid 激活函數(shù)的神經(jīng)元模型,它的數(shù)學(xué)模型可以寫為
o^1 = \sigma(w^1x+b^1)
其中

  • 變量的上標(biāo)表示層數(shù),如 o^1 表示第一個(gè)隱藏層的輸出
  • x 表示網(wǎng)絡(luò)的輸入

單個(gè)神經(jīng)元模型如下圖所示

  • 輸入節(jié)點(diǎn)數(shù)為 J
    • 其中輸入第 j 個(gè)節(jié)點(diǎn)到輸出 o^1 的權(quán)值連接記為 w^1_{j1}
  • 上標(biāo)表示權(quán)值屬于的層數(shù),下標(biāo)表示當(dāng)前連接的起始節(jié)點(diǎn)號(hào)和終止節(jié)點(diǎn)號(hào)
    • 如下標(biāo) j1 表示上一層的第 j 號(hào)節(jié)點(diǎn)到當(dāng)前層的 1 號(hào)節(jié)點(diǎn)
  • 未經(jīng)過激活函數(shù)的輸出變量為 z_1^1,經(jīng)過激活函數(shù)之后的輸出為 o_1^1
  • 由于只有一個(gè)輸出節(jié)點(diǎn),故 o_1^1 = o^1
Screenshot-20200108115244-692x251.png

下面我們來(lái)計(jì)算均方差算是函數(shù)的梯度

由于單個(gè)神經(jīng)元只有一個(gè)輸出,那么損失函數(shù)可以表示為
L = \frac{1}{2}(o_1^1 - t)^2
添加 \frac{1}{2} 是為了計(jì)算方便,我們以權(quán)值連接的第 j\in[1,J] 號(hào)節(jié)點(diǎn)的權(quán)值 w_{j1} 為例,考慮損失函數(shù) L 對(duì)其的偏導(dǎo)數(shù) \frac{\partial L}{\partial w_{j1}}
\frac{\partial L}{\partial w_{j1}} = (o_1 - t)\frac{\partial o_1}{\partial w_{j1}}
由于 o_1 = \sigma(z_1) ,由上面的推導(dǎo)可知 Sigmoid 函數(shù)的導(dǎo)數(shù) \sigma' = \sigma(1-\sigma)
\frac{\partial L}{\partial w_{j1}} = (o_1 - t)\frac{\partial \sigma(z_1)}{\partial w_{j1}}

= (o_1-t)\sigma(z_1)(1-\sigma(z_1))\frac{\partial z_1}{\partial w_{j1}}

\sigma(z_1) 寫成 o_1
= (o_1-t)o_1(1-o_1)\frac{\partial z_1}{\partial w_{j1}}
由于 \frac{\partial z_1}{\partial w_{j1}} = x_j
\frac{\partial L}{\partial w_{j1}} = (o_1-t)o_1(1-o_1)x_j
從上式可以看到,誤差對(duì)權(quán)值 w_{j1} 的偏導(dǎo)數(shù)只與輸出值 o_1 、真實(shí)值 t 以及當(dāng)前權(quán)值連接的輸 x_j 有關(guān)

全鏈接層梯度

我們把單個(gè)神經(jīng)元模型推廣到單層全連接層的網(wǎng)絡(luò)上,如下圖所示。輸入層通過一個(gè)全連接層得到輸出向量 o^1 ,與真實(shí)標(biāo)簽向量 t 計(jì)算均方差。輸入節(jié)點(diǎn)數(shù)為 J ,輸出節(jié)點(diǎn)數(shù)為 K 。

Screenshot-20200108124008-705x259.png

與單個(gè)神經(jīng)元不同,全鏈接層有多個(gè)輸出節(jié)點(diǎn) o_1^1, o_2^1, o_3^1,...,o_K^1 ,每個(gè)輸出節(jié)點(diǎn)對(duì)應(yīng)不同真實(shí)標(biāo)簽 t_1, t_2, t_3,..., t_K ,均方誤差可以表示為
L = \frac{1}{2}\sum_{i=1}^K(o_i^1-t_i)^2
由于 \frac{\partial L}{\partial w_{jk}} 只與 o_k^1 有關(guān)聯(lián),上式中的求和符號(hào)可以去掉,即 i = k
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)\frac{\partial o_k}{\partial w_{jk}}
o_k=\sigma(z_k) 帶入
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)\frac{\partial \sigma(z_k)}{\partial w_{jk}}
考慮 Sigmoid 函數(shù)的導(dǎo)數(shù) \sigma' = \sigma(1-\sigma)
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)\sigma(z_k)(1-\sigma(z_k))\frac{\partial z_k^1}{\partial w_{jk}}
\sigma(z_k) 記為 o_k
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)o_k(1-o_k)\frac{\partial z_k^1}{\partial w_{jk}}
最終可得
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)o_k(1-o_k)\cdot x_j
由此可以看到,某條連接 w_{jk} 上面的連接,只與當(dāng)前連接的輸出節(jié)點(diǎn) o_k^1 ,對(duì)應(yīng)的真實(shí)值節(jié)點(diǎn)的標(biāo)簽 t_k^1 ,以及對(duì)應(yīng)的輸入節(jié)點(diǎn) x 有關(guān)。

我們令 \delta_k = (o_k-t_k)o_k(1-o_k) ,則 \frac{\partial L}{\partial w_{jk}} 可以表達(dá)為
\frac{\partial L}{\partial w_{jk}}=\delta_k\cdot x_j
其中 \delta _k 變量表征連接線的終止節(jié)點(diǎn)的梯度傳播的某種特性,使用 \delta_k 表示后,\frac{\partial L}{\partial w_{jk}} 偏導(dǎo)數(shù)只與當(dāng)前連接的起始節(jié)點(diǎn) x_j,終止節(jié)點(diǎn)處 \delta_k 有關(guān),理解起來(lái)比較直觀。

反向傳播算法

看到這里大家也不容易,畢竟這么多公式哈哈哈,不過激動(dòng)的時(shí)刻到了

先回顧下輸出層的偏導(dǎo)數(shù)公式
\frac{\partial L}{\partial w_{jk}} = (o_k-t_k)o_k(1-o_k)\cdot x_j = \delta_k \cdot x_j
多層全連接層如下圖所示

  • 輸出節(jié)點(diǎn)數(shù)為 K ,輸出 o^k = [o_1^k, o_2^k, o_3^k,..., o_k^k]
  • 倒數(shù)的二層的節(jié)點(diǎn)數(shù)為 J ,輸出為 o^J=[o_1^J, o_2^J,..., o_J^J]
  • 倒數(shù)第三層的節(jié)點(diǎn)數(shù)為 I ,輸出為 o^I = [o_1^I, o_2^I,..., o_I^I]
Screenshot-20200108132457-739x244.png

均方誤差函數(shù)
\frac{\partial L}{\partial w_{ij}}=\frac{\partial}{\partial w_{ij}}\frac{1}{2}\sum_{k}(o_k-t_k)2
由于 L 通過每個(gè)輸出節(jié)點(diǎn) o_kw_i 相關(guān)聯(lián),故此處不能去掉求和符號(hào)
\frac{\partial L}{\partial w_{ij}}=\sum_k(o_k-t_k)\frac{\partial o_k}{\partial w_{ij}}
o_k=\sigma(z_k) 帶入
\frac{\partial L}{\partial w_{ij}}=\sum_k(o_k-t_k)\frac{\partial \sigma(z_k)}{\partial w_{ij}}
Sigmoid 函數(shù)的導(dǎo)數(shù) \sigma' = \sigma(1-\sigma) ,繼續(xù)求導(dǎo),并將 \sigma(z_k) 寫回 o_k
\frac{\partial L}{\partial w_{ij}}=\sum_k(o_k-t_k)o_k(1-o_k)\frac{\partial z_k}{\partial w_{ij}}
對(duì)于 \frac{\partial z_k}{\partial w_{ij}} 可以應(yīng)用鏈?zhǔn)椒▌t分解為
\frac{\partial z_k}{\partial w_{ij}} = \frac{\partial z_k}{o_j}\cdot \frac{\partial o_j}{\partial w_{ij}}
由圖可知 \left(z_k = o_j \cdot w_{jk} + b_k\right) ,故有
\frac{\partial z_k}{o_j} = w_{jk}
所以
\frac{\partial L}{\partial w_{ij}}=\sum_k(o_k-t_k)o_k(1-o_k)w_{jk}\cdot\frac{\partial o_j}{\partial w_{ij}}
考慮到 \frac{\partial o_j}{\partial w_{ij}}k 無(wú)關(guān),可將其提取出來(lái)
\frac{\partial L}{\partial w_{ij}}=\frac{\partial o_j}{\partial w_{ij}}\cdot\sum_k(o_k-t_k)o_k(1-o_k)w_{jk}
再一次有 o_k=\sigma(z_k) ,并利用 Sigmoid 函數(shù)的導(dǎo)數(shù) \sigma' = \sigma(1-\sigma)
\frac{\partial L}{\partial w_{ij}}= o_j(1-o_j)\frac{\partial z_j}{\partial w_{ij}} \cdot\sum_k(o_k-t_k)o_k(1-o_k)w_{jk}
由于 \frac{\partial z_j}{\partial w_{ij}} = o_i \left(z_j = o_i\cdot w_{ij} + b_j\right)
\frac{\partial L}{\partial w_{ij}}= o_j(1-o_j)o_i \cdot\sum_k(o_k-t_k)o_k(1-o_k)w_{jk}
其中 \delta _k^K = (o_k-t_k)o_k(1-o_k) ,則
\frac{\partial L}{\partial w_{ij}}= o_j(1-o_j)o_i \cdot\sum_k\delta _k^K\cdot w_{jk}
仿照輸出層的書寫方式,定義
\delta_j^J = o_j(1-o_j) \cdot \sum_k \delta _k^K\cdot w_{jk}
此時(shí) \frac{\partial L}{\partial w_{ij}} 可以寫為當(dāng)前連接的起始節(jié)點(diǎn)的輸出值 o_i 與終止節(jié)點(diǎn) j 的梯度信息 \delta _j^J 的簡(jiǎn)單相乘運(yùn)算:
\frac{\partial L}{\partial w_{ij}} = \delta_j^J\cdot o_i^I
通過定義 \delta 變量,每一層的梯度表達(dá)式變得更加清晰簡(jiǎn)潔,其中 \delta 可以簡(jiǎn)單理解為當(dāng)前連接 w_{ij} 對(duì)誤差函數(shù)的貢獻(xiàn)值。

總結(jié)

輸出層:
\frac{\partial L}{\partial w_{jk}} = \delta _k^K\cdot o_j

\delta _k^K = (o_k-t_k)o_k(1-o_k)

倒數(shù)第二層:
\frac{\partial L}{\partial w_{ij}} = \delta _j^J\cdot o_i

\delta_j^J = o_j(1-o_j) \cdot \sum_k \delta _k^K\cdot w_{jk}

倒數(shù)第三層:
\frac{\partial L}{\partial w_{ni}} = \delta _i^I\cdot o_n

\delta _i^I = o_i(1-o_i)\cdot \sum_j\delta_j^J\cdot w_{ij}

其中 o_n 為倒數(shù)第三層的輸入,即倒數(shù)第四層的輸出

依照此規(guī)律,只需要循環(huán)迭代計(jì)算每一層每個(gè)節(jié)點(diǎn)的 \delta _k^K, \delta_j^J, \delta_i^I,... 等值即可求得當(dāng)前層的偏導(dǎo)數(shù),從而得到每層權(quán)值矩陣 W 的梯度,再通過梯度下降算法迭代優(yōu)化網(wǎng)絡(luò)參數(shù)即可。

好了,反向傳播算法推導(dǎo)完畢,代碼實(shí)現(xiàn)可以參考另一篇博客神經(jīng)網(wǎng)絡(luò)之動(dòng)手實(shí)現(xiàn)反向傳播(BP)算法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容