BP 算法的訓(xùn)練過程形葬,各種博客和參考書已經(jīng)講的很清楚了,但不管是周志華的《機(jī)器學(xué)習(xí)》码荔,還是林軒田的《機(jī)器學(xué)習(xí)技法》漩勤,都只是對(duì) 3 層的神經(jīng)網(wǎng)絡(luò)的訓(xùn)練做了非向量化的推導(dǎo)。本文將結(jié)合 Andrew Ng 的最新視頻缩搅,從向量和矩陣運(yùn)算的角度推一遍任意層神經(jīng)網(wǎng)絡(luò)(全連接)的訓(xùn)練算法越败。
為什么要公式向量化
從工程的角度來講,向量化可以極大的加快程序的運(yùn)行速度硼瓣。舉一個(gè)例子究飞,求兩個(gè)向量(列向量)的內(nèi)積,你可能會(huì)寫出以下兩個(gè)公式:
在實(shí)現(xiàn)的過程中,公式 (1) 使用了 for 循環(huán)亿傅,公式 (2) 使用了優(yōu)化過的矩陣乘法媒峡,第一種的速度會(huì)遠(yuǎn)快于第二種。
符號(hào)約定
符號(hào) | 意義 |
---|---|
l |
表示神經(jīng)網(wǎng)絡(luò)的層數(shù) |
m |
batch_size |
C |
表示每一層的神經(jīng)元的個(gè)數(shù) |
J |
cost function |
a |
學(xué)習(xí)率 |
符號(hào) | shape | 意義 | i 的取值 |
---|---|---|---|
Z[i] |
(Ci, ) |
表示第 i 層的輸入(未經(jīng)激活函數(shù)) | 2 - l |
A[i] |
(Ci, ) |
表示第 i 層的輸入 | 1 - l |
w[i] |
(Ci, Ci-1) |
表示第 i 層神經(jīng)元的權(quán)重矩陣 | 2 - l |
b[i] |
(Ci, ) |
表示第 i 層神經(jīng)元的偏置(bias) | 2 - l |
正向傳播過程
輸入:
A[1]
袱蜡,即 X
輸出:A[l]
丝蹭,即 y^
對(duì)于i = 2, 3, ... l
其中
式子中的 *
符號(hào)指的是智能乘法,表示矩陣的對(duì)應(yīng)位置相乘坪蚁。
誤差反向傳導(dǎo)過程
BP 算法的原理是利用鏈?zhǔn)椒▌t奔穿,對(duì)于每一個(gè)路徑只訪問一次就能求頂點(diǎn)對(duì)所有下層節(jié)點(diǎn)的偏導(dǎo)值。
先來看看 J
對(duì) w[l]
的導(dǎo)數(shù)
其中
再來看 J
對(duì) w[l-1]
的導(dǎo)數(shù)
通過觀察 dw[l]
和 dw[l-1]
敏晤,可以找到遞推的規(guī)律:
BP 算法前向遞推的規(guī)律:
起始條件
對(duì)于i = l - 1, l - 2, ... 2
贱田,有
經(jīng)過了一輪循環(huán),求出了神經(jīng)網(wǎng)絡(luò)各層的 dw
嘴脾,然后按照下式更新網(wǎng)絡(luò)參數(shù):
這就完成了一個(gè) epoch 的訓(xùn)練男摧。
技巧
上述算法的缺點(diǎn)是,由于在后向傳播的過程中译打,需要求激活函數(shù) φ
對(duì) 輸入 Z[i]
的導(dǎo)數(shù)耗拓,所以我們?cè)谶M(jìn)行前向傳播的過程中,需要保存一下每一層的 Z
的值奏司,這無疑增大了內(nèi)存的消耗乔询,在這里我們有一個(gè)技巧:
當(dāng)激活函數(shù)為 Sigomid、Tanh 和 ReLU 時(shí)韵洋,其導(dǎo)數(shù)可由其函數(shù)值表示竿刁,例如:Sigomid 函數(shù)的導(dǎo)數(shù)為
f(x) * (1 - f(x))
,Tanh 函數(shù)的導(dǎo)數(shù)為1 - f(x)^2
搪缨。
所以食拜,在參與上式 dZ
的運(yùn)算中,利用函數(shù)的化簡(jiǎn)可以約分掉與 Z[i]
相關(guān)的項(xiàng)(用 A[i]
替代了) 的值副编,這樣我們就可以適當(dāng)?shù)淖儞Q一下迭代公式负甸,使 Z[i]
不出現(xiàn)在公式中,這樣就不用再額外存儲(chǔ) Z
了齿桃。
實(shí)現(xiàn)
具體的 Python 實(shí)現(xiàn)惑惶,請(qǐng)點(diǎn)擊這里
參考資料
- Neural Networks and Deep Learning, Andrew Ng.
- 如何直觀地解釋 back propagation 算法? - 胡逸夫的回答 - 知乎