上一篇 9 “驅(qū)魔”之反向傳播大法引出了反向傳播算法——神經(jīng)網(wǎng)絡(luò)的引擎,并在最后窺探了它的全貌。本篇將詳細(xì)的討論反向傳播各方面的細(xì)節(jié)。盡管它被TensorFlow封裝的很好,但仍強(qiáng)烈建議把它作為人工神經(jīng)網(wǎng)絡(luò)的基本功,理解并掌握它,回報(bào)巨大。
《Neural Network and Deep Learning》的作者Nielsen寫(xiě)道:
It actually gives us detailed insights into how changing the weights and biases changes the overall behaviour of the network. That's well worth studying in detail.
實(shí)際上它(反向傳播算法)給了我們更加細(xì)致的洞察:如何通過(guò)改變權(quán)重和偏置來(lái)改變網(wǎng)絡(luò)的整體行為。非常值得深入的學(xué)習(xí)。
好在這里面最困難的——推導(dǎo)反向傳播四大公式,也并非看上去那么難:keep calm and use chain rule(鏈?zhǔn)角髮?dǎo)法則)。
先說(shuō)前饋
為了能說(shuō)清楚“反向傳播”(Backpropagation),得先從“前饋”(Feedforward)說(shuō)起。
到目前為止討論的神經(jīng)網(wǎng)絡(luò),都是以上一層的輸出,作為下一層的輸入,其中沒(méi)有回路。也就是說(shuō)網(wǎng)絡(luò)中的信息總是從輸入層向輸出層傳播,不存在反饋(Feedback)。這樣的網(wǎng)絡(luò)就是前饋神經(jīng)網(wǎng)絡(luò)。
對(duì)于前饋神經(jīng)網(wǎng)絡(luò),當(dāng)確定了網(wǎng)絡(luò)的層數(shù),每層神經(jīng)元的個(gè)數(shù),以及神經(jīng)元的激活函數(shù),那么給定輸入,通過(guò)“層層前饋”就能計(jì)算輸出。用ajl來(lái)表示第l層中第j個(gè)神經(jīng)元的輸出,那么輸出的表達(dá)式為:
上式是l層第j個(gè)單個(gè)神經(jīng)元的輸出表達(dá)式,如果用矩陣來(lái)表示某一層所有神經(jīng)元的輸出的話(huà),形式會(huì)更加的簡(jiǎn)單和優(yōu)美:
上式表示了l層神經(jīng)元的輸出與輸入(也就是上一層神經(jīng)元的輸出)之間的關(guān)系。
為了對(duì)上式的矩陣操作看的更加清晰,仍用之前的3層感知器網(wǎng)絡(luò)舉例。
簡(jiǎn)單回顧下矩陣的乘法的行列約束:Alm·Bmn=Cln,即一個(gè)l行m列的矩陣A與一個(gè)m行n列的矩陣B相乘,那么結(jié)果矩陣C是l行n列。
套用al的公式,計(jì)算a2(第二層輸出):
等價(jià)的微觀視角:
有了前饋表達(dá)式,就可以計(jì)算出網(wǎng)絡(luò)各層的輸出al,乃至最終的輸出aL(L代表網(wǎng)絡(luò)的總層數(shù))。這樣,當(dāng)前模型的損失也能計(jì)算出來(lái)了,仍以均方誤差(MSE)作為損失函數(shù):
用aL(x)代替下式中的output(x),有:
其中對(duì)于單個(gè)獨(dú)立樣本Cx來(lái)說(shuō),有:
從上式的形式上來(lái)看,也可以把損失Cx看成神經(jīng)網(wǎng)絡(luò)輸出aL的函數(shù)。
什么在反向傳播?
前面介紹了信息的前饋,也明說(shuō)了信息沒(méi)有“反向回饋”。那么當(dāng)我們?cè)谡f(shuō)反向傳播時(shí),我們?cè)谡f(shuō)什么?
答案是“神經(jīng)元的誤差”,“誤差”在反向傳播。
為了能從形式上看到這個(gè)“誤差”,對(duì)于第l層的第j個(gè)神經(jīng)元,定義神經(jīng)元誤差:
它是一個(gè)純粹的形式定義,表達(dá)式的含義是:某個(gè)神經(jīng)元的誤差是損失函數(shù)C對(duì)于該神經(jīng)元加權(quán)輸入z的偏導(dǎo)數(shù),其中加權(quán)輸入z就是神經(jīng)元激活函數(shù)的輸入:
之所以說(shuō)誤差會(huì)沿著網(wǎng)絡(luò)反方向傳播,主要基于對(duì)反向傳播第2個(gè)公式的(BP2)的觀察和理解。BP2顯示:被定義為神經(jīng)元誤差的δl,是由比它更靠近輸出層神經(jīng)元的誤差δl+1決定的:
基于這個(gè)數(shù)學(xué)形式,可以非常清晰和形象的看到“誤差”的確是在反方向傳播。
再次列出反向傳播4大公式:
此時(shí)回看BP1,就會(huì)意識(shí)到BP1與BP2配合之強(qiáng)大了:只要通過(guò)BP1計(jì)算出輸出層的δL,那么就可以通過(guò)BP2“層層反傳”,計(jì)算出任意一層的δl。而損失函數(shù)C對(duì)于任意層中的wl和bl偏導(dǎo)數(shù)也就可以通過(guò)BP3和BP4得到了。
推導(dǎo)前的兩個(gè)準(zhǔn)備
Hadamard乘積
在BP1與BP2中都用到了一個(gè)符號(hào)“⊙”,它連接兩個(gè)矩陣完全相同的矩陣,表示Hadamard(哈達(dá)瑪)乘積。它的運(yùn)算規(guī)則非常的簡(jiǎn)單(僅次于矩陣加減法),就是兩矩陣的對(duì)應(yīng)元素相乘。一個(gè)例子:
鏈?zhǔn)角髮?dǎo)法則
BP1推導(dǎo)
BP1的另一種表達(dá)方式是分量表達(dá)式,對(duì)其進(jìn)行推導(dǎo)。
對(duì)δjl的定義,運(yùn)用鏈?zhǔn)角髮?dǎo)法則:
只有當(dāng)k=j時(shí),ak=jL才與zjL有關(guān)系(ajL = σ(zjL))。k≠j時(shí),?akL/?zjL就消失了:
因?yàn)閍jL = σ(zjL),上式中?ajL/?zjL可以寫(xiě)為σ'(zjL),即推導(dǎo)出BP1:
BP1給出了計(jì)算δjl的方法,計(jì)算起來(lái)比看上去要簡(jiǎn)單的多。把δjl的計(jì)算拆分成左右兩個(gè)部分:?C/?ajL和σ'(zjL)。
如果我們使用均方差作為損失函數(shù)C,那么單個(gè)樣本的情況下有:
所以?C/?ajL = (aj - yj)。
如果σ是sigmoid函數(shù),有σ'(x) = σ(x) * (1 - σ(x))(可自行證明)。那么σ'(zjL) = σ(zjL) * (1 - σ(zjL)),其中zjL是通過(guò)前饋計(jì)算獲得的。
BP2推導(dǎo)
對(duì)BP2的分量表達(dá)式進(jìn)行推導(dǎo):
BP2會(huì)稍微復(fù)雜一點(diǎn)。要想辦法將δkl+1 = ?C/?zkl+1引入,仍然應(yīng)用鏈?zhǔn)角髮?dǎo)法則:
為了求?zkl+1/?zjl,根據(jù)定義有:
計(jì)算?zkl+1/?zjl,得到
再將上式代回[推導(dǎo)BP2:1],即推導(dǎo)出BP2:
BP3推導(dǎo)
BP3是求取損失C對(duì)于偏置b的偏導(dǎo)數(shù),性質(zhì)非常好,居然就是δjl本身:
利用鏈?zhǔn)角髮?dǎo)法則,引入?C/?zjl:
因?yàn)橛校?/p>
即推出BP3:
BP4推導(dǎo)
BP4是求取損失C對(duì)于偏置w的偏導(dǎo)數(shù):
利用鏈?zhǔn)角髮?dǎo)法則,引入?C/?zjl:
即推出BP4:
如果沒(méi)有反向傳播算法
之前提到,由于神經(jīng)網(wǎng)絡(luò)的權(quán)重參數(shù)過(guò)多,通過(guò)解偏導(dǎo)數(shù)方程來(lái)得到梯度是不現(xiàn)實(shí)的。那么在反向傳播算法被應(yīng)用之前,難道就真的沒(méi)有任何辦法嗎?答案是有的,利用導(dǎo)數(shù)的定義即可:
wj表示第j個(gè)權(quán)重,對(duì)于wj上一個(gè)非常小的增量,通過(guò)網(wǎng)絡(luò)的層層傳遞,最終會(huì)導(dǎo)致的損失函數(shù)的變化。在上式中,對(duì)wj求導(dǎo),可以近似成等式右邊的形式。對(duì)于偏置求導(dǎo)也是同理。
這個(gè)算法并不復(fù)雜,易懂易實(shí)現(xiàn)。看似比反向傳播四大公式簡(jiǎn)單很多。
接下來(lái)我們算下計(jì)算量的帳,就不那么美好了。假設(shè)整個(gè)網(wǎng)絡(luò)中有30000個(gè)權(quán)重(現(xiàn)實(shí)中非常小巧的網(wǎng)絡(luò)),那么對(duì)于每一個(gè)樣本,要得到“損失”對(duì)所有30000個(gè)參數(shù)的偏導(dǎo),就要進(jìn)行30001次前向傳播計(jì)算(多出的1次零頭是求初始的C(w))。這是因?yàn)閷?duì)每個(gè)權(quán)重求偏導(dǎo),都需要獲得當(dāng)前的“損失”,而“損失”是由網(wǎng)絡(luò)最后一層輸出決定的。
對(duì)于海量的訓(xùn)練樣本,以及現(xiàn)實(shí)中更加龐大的網(wǎng)絡(luò)結(jié)構(gòu),計(jì)算量就是天文數(shù)字了。
反觀反向傳播算法,盡管其公式剛開(kāi)始看上去有些凌亂(其實(shí)看久了是十分具有美感的),但是對(duì)于每一個(gè)樣本,一趟前向傳播,再加一趟反向傳播,30000個(gè)權(quán)重就可以全部計(jì)算出來(lái)了。這才讓大規(guī)模的網(wǎng)絡(luò)訓(xùn)練具有了現(xiàn)實(shí)意義。
上一篇 9 “驅(qū)魔”之反傳大法
下一篇 11 74行Python實(shí)現(xiàn)手寫(xiě)體數(shù)字識(shí)別
共享協(xié)議:署名-非商業(yè)性使用-禁止演繹(CC BY-NC-ND 3.0 CN)
轉(zhuǎn)載請(qǐng)注明:作者黑猿大叔(簡(jiǎn)書(shū))