0
雷鋒網(wǎng)按:本文原作者李飛騰,本文整理自知乎專欄——數(shù)字編程。雷鋒網(wǎng)已獲得轉(zhuǎn)載授權(quán)。
如果能二秒內(nèi)在腦袋里解出下面的問題,本文便結(jié)束了。
已知:,其中
。
求:,
,
。
到這里,請(qǐng)耐心看完下面的公式推導(dǎo),無需長久心里建設(shè)。
首先,反向傳播的數(shù)學(xué)原理是 “求導(dǎo)的鏈?zhǔn)椒▌t” :
設(shè)和
為
的可導(dǎo)函數(shù),則
。
接下來介紹
矩陣、向量求導(dǎo)的維數(shù)相容原則
利用維數(shù)相容原則快速推導(dǎo)反向傳播
編程實(shí)現(xiàn)前向傳播、反向傳播
卷積神經(jīng)網(wǎng)絡(luò)的反向傳播
這一節(jié)展示如何使用鏈?zhǔn)椒▌t、轉(zhuǎn)置、組合等技巧來快速完成對(duì)矩陣、向量的求導(dǎo)
一個(gè)原則維數(shù)相容,實(shí)質(zhì)是多元微分基本知識(shí),沒有在課本中找到下列內(nèi)容,維數(shù)相容原則是我個(gè)人總結(jié):
維數(shù)相容原則:通過前后換序、轉(zhuǎn)置 使求導(dǎo)結(jié)果滿足矩陣乘法且結(jié)果維數(shù)滿足下式:
如果,
,那么
。
利用維數(shù)相容原則解上例:
step1:把所有參數(shù)當(dāng)做實(shí)數(shù)來求導(dǎo),,
依據(jù)鏈?zhǔn)椒▌t有,
,
可以看出除了,
和
的求導(dǎo)結(jié)果在維數(shù)上連矩陣乘法都不能滿足。
step2:根據(jù) step1 的求導(dǎo)結(jié)果,依據(jù)維數(shù)相容原則做調(diào)整:前后換序、轉(zhuǎn)置
依據(jù)維數(shù)相容原則,但
中
、
,自然得調(diào)整為
;
同理:,但
中
、
,那么通過換序、轉(zhuǎn)置我們可以得到維數(shù)相容的結(jié)果
。
對(duì)于矩陣、向量求導(dǎo):
“當(dāng)做一維實(shí)數(shù)使用鏈?zhǔn)椒▌t求導(dǎo),然后做維數(shù)相容調(diào)整,使之符合矩陣乘法原則且維數(shù)相容” 是快速準(zhǔn)確的策略;
“對(duì)單個(gè)元素求導(dǎo)、再整理成矩陣形式” 這種方式整理是困難的、過程是緩慢的,結(jié)果是易出錯(cuò)的(不信你試試)。
如何證明經(jīng)過維數(shù)相容原則調(diào)整后的結(jié)果是正確的呢?直覺!簡單就是美...
神經(jīng)網(wǎng)絡(luò)的反向傳播求得 “各層” 參數(shù)和
的導(dǎo)數(shù),使用梯度下降(一階 GD、SGD,二階 LBFGS、共軛梯度等)優(yōu)化目標(biāo)函數(shù)。
接下來,展示不使用下標(biāo)的記法(,
or
)直接對(duì)
和
求導(dǎo),反向傳播是鏈?zhǔn)椒▌t和維數(shù)相容原則的完美體現(xiàn),對(duì)每一層參數(shù)的求導(dǎo)利用上一層的中間結(jié)果完成。
這里的標(biāo)號(hào),參考 UFLDL 教程 - Ufldl
前向傳播:
(公式 1)
(公式 2)
為第
層的中間結(jié)果,
為第
層的激活值,其中第
層包含元素:輸入
,參數(shù)
、
,激活函數(shù)
,中間結(jié)果
,輸出
。
設(shè)神經(jīng)網(wǎng)絡(luò)的損失函數(shù)為(這里不給出具體公式,可以是交叉熵、MSE 等),根據(jù)鏈?zhǔn)椒▌t有:
這里記 ,其中
、
可由 公式 1 得出,
加轉(zhuǎn)置符號(hào)
是根據(jù)維數(shù)相容原則作出的調(diào)整。
如何求 ? 可使用如下遞推(需根據(jù)維數(shù)相容原則作出調(diào)整):
其中、
。
那么我們可以從最頂層逐層往下,便可以遞推求得每一層的
注意:是逐維求導(dǎo),在公式中是點(diǎn)乘的形式。
反向傳播整個(gè)流程如下:
1) 進(jìn)行前向傳播計(jì)算,利用前向傳播公式,得到隱藏層和輸出層 的激活值。
2) 對(duì)輸出層 (第層),計(jì)算殘差:
(不同損失函數(shù),結(jié)果不同,這里不給出具體形式)
3) 對(duì)于的隱藏層,計(jì)算:
4) 計(jì)算各層參數(shù)、
偏導(dǎo)數(shù):
大部分開源 library(如:caffe,Kaldi/src/{nnet1,nnet2})的實(shí)現(xiàn)通常把、
作為一個(gè) layer,激活函數(shù)
作為一個(gè) layer(如:sigmoid、relu、softplus、softmax)。
反向傳播時(shí)分清楚該層的輸入、輸出即能正確編程實(shí)現(xiàn), 如:
(公式 1)
(公式 2)
(1) 式 AffineTransform/FullConnected 層,以下是偽代碼:
注: out_diff = 是上一層(Softmax 或 Sigmoid/ReLU 的 in_diff)已經(jīng)求得:
(公式 1-1)
(公式 1-2)
(公式 1-3)
(2) 式激活函數(shù)層(以 Sigmoid 為例)
注:out_diff = 是上一層 AffineTransform 的 in_diff,已經(jīng)求得,
在實(shí)際編程實(shí)現(xiàn)時(shí),in、out 可能是矩陣 (通常以一行存儲(chǔ)一個(gè)輸入向量,矩陣的行數(shù)就是 batch_size),那么上面的 C++ 代碼就要做出變化(改變前后順序、轉(zhuǎn)置,把函數(shù)參數(shù)的 Vector 換成 Matrix,此時(shí) Matrix out_diff 每一行就要存儲(chǔ)對(duì)應(yīng)一個(gè) Vector 的 diff,在 update 的時(shí)候要做這個(gè) batch 的加和,這個(gè)加和可以通過矩陣相乘 out_diff*input(適當(dāng)?shù)霓D(zhuǎn)置)得到。
如果熟悉 SVD 分解的過程,通過 SVD 逆過程就可以輕松理解這種通過乘積來做加和的技巧。
丟掉那些下標(biāo)記法吧!
卷積怎么求導(dǎo)呢?實(shí)際上卷積可以通過矩陣乘法來實(shí)現(xiàn)(是否旋轉(zhuǎn)無所謂的,對(duì)稱處理,caffe 里面是不是有 image2col),當(dāng)然也可以使用 FFT 在頻率域做加法。
那么既然通過矩陣乘法,維數(shù)相容原則仍然可以運(yùn)用,CNN 求導(dǎo)比 DNN 復(fù)雜一些,要做些累加的操作。具體怎么做還要看編程時(shí)選擇怎樣的策略、數(shù)據(jù)結(jié)構(gòu)。
快速矩陣、向量求導(dǎo)之維數(shù)相容大法已成。
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。