【机器学习】详解 BackPropagation 反向传播算法!
首先介紹一下鏈?zhǔn)椒▌t
假如我們要求z對x1的偏導(dǎo)數(shù),那么勢必得先求z對t1的偏導(dǎo)數(shù),這就是鏈?zhǔn)椒▌t,一環(huán)扣一環(huán)
BackPropagation(BP)正是基于鏈?zhǔn)椒▌t的,接下來用簡單的前向傳播網(wǎng)絡(luò)為例來解釋。里面有線的神經(jīng)元代表的sigmoid函數(shù),y_1代表的是經(jīng)過模型預(yù)測出來的,y_1 = w1 * x1 + w2 * x2,而y^1代表的是實(shí)際值,最后是預(yù)測值與實(shí)際值之間的誤差,l_1 = 1/2 * (y_1 - y^1)^2,l_2同理。總的錯誤是E = l_1 + l_2。
在神經(jīng)網(wǎng)絡(luò)中我們采用梯度下降(Gradient Descent)來進(jìn)行參數(shù)更新,最終找到最優(yōu)參數(shù)。可是離E最近的不是w1,首先我們需要求出E對l_1的偏導(dǎo),接著求l_1對于最近神經(jīng)元sigmoid中變量的導(dǎo)數(shù),最后再求y_0對于w1的偏導(dǎo),進(jìn)行梯度更新。
這便是神經(jīng)網(wǎng)絡(luò)中的BP算法,與以往的正向傳播不同,它應(yīng)該是從反向的角度不斷優(yōu)化
這里只是用了一層隱含層,可以看的出來一個(gè)參數(shù)的梯度往往與幾個(gè)量產(chǎn)生關(guān)系:
最終y被預(yù)測的值。這往往取決于你的激活函數(shù),如這里采用sigmoid
中間對激活函數(shù)進(jìn)行求導(dǎo)的值
輸入的向量,即為x
推廣到N層隱含層,只是乘的東西變多了,但是每個(gè)式子所真正代表的含義是一樣的。
換個(gè)角度說,在深度學(xué)習(xí)梯度下降的時(shí)候會出現(xiàn)比較常見的兩類問題,梯度消失以及梯度爆炸很可能就是這些量之間出了問題,對模型造成了影響。
1、梯度消失(Gradient Vanishing)。意思是梯度越來越小,一個(gè)很小的數(shù)再乘上幾個(gè)較小的數(shù),那么整體的結(jié)果就會變得非常的小。那么導(dǎo)致的可能原因有哪些呢?我們由靠近E的方向向后分析。
激活函數(shù)。y_1是最后經(jīng)過激活函數(shù)的結(jié)果,如果激活函數(shù)不能很好地反映一開始輸入時(shí)的情況,那么就很有可能出問題。sigmoid函數(shù)的性質(zhì)是正數(shù)輸出為大于0.5,負(fù)數(shù)輸出為小于0.5,因?yàn)楹瘮?shù)的值域?yàn)?0,1),所以也常常被用作二分類的激活函數(shù),用以表示概率。但是,當(dāng)x比較靠近原點(diǎn)的時(shí)候,x變化時(shí),函數(shù)的輸出也會發(fā)生明顯的變化,可是,當(dāng)x相當(dāng)大的時(shí)候,sigmoid幾乎已經(jīng)是無動于衷了,x相當(dāng)小的時(shí)候同理。這里不妨具體舉個(gè)二分類的例子,比如說用0,1代表標(biāo)簽,疊了一層神經(jīng)網(wǎng)絡(luò),sigmoid函數(shù)作為激活函數(shù)。E對l_1的偏導(dǎo)極大程度將取決于y_1,因?yàn)闃?biāo)簽就是0,1嘛。就算輸入端的x,w都比較大,那么經(jīng)過sigmoid壓縮之后就會變得很小,只有一層的時(shí)候其實(shí)還好,但是當(dāng)層數(shù)變多之后呢,sigmoid函數(shù)假如說每一層都當(dāng)做是激活函數(shù),那么最后E對l_1的偏導(dǎo)將是十分地小,盡管x,w代表著一些信息,可經(jīng)過sigmoid壓縮之后信息發(fā)生了丟失,梯度無法完成真正意義上的傳播,乘上一個(gè)很小的數(shù),那么整個(gè)梯度會越來越小,梯度越小,說明幾乎快收斂了。換句話說,幾乎沒多久就已經(jīng)收斂了。
另一種思路是從公式(4)出發(fā),無論y_0取何值,公式(4)的輸出值總是介于(0,1/4](當(dāng)然具體邊界處是否能取到取決于具體變量的取值),證明:
因?yàn)椴粩喑松弦粋€(gè)比較小的數(shù)字,所以層數(shù)一多,那么整個(gè)梯度的值就會變得十分小,而且這個(gè)是由sigmoid本身導(dǎo)致,應(yīng)該是梯度消失的主因。
解決方法可以是換個(gè)激活函數(shù),比如RELU就不錯,或者RELU的變種。
2、梯度爆炸(Gradient Exploding)。意思是梯度越來越大,更新的時(shí)候完全起不到優(yōu)化的作用。其實(shí)梯度爆炸發(fā)生的頻率遠(yuǎn)小于梯度消失的頻率。如果發(fā)生了,可以用梯度削減(Gradient Clipping)。
梯度削減。首先設(shè)置一個(gè)clip_gradient作為梯度閾值,然后按照往常一樣求出各個(gè)梯度,不一樣的是,我們沒有立馬進(jìn)行更新,而是求出這些梯度的L2范數(shù),注意這里的L2范數(shù)與嶺回歸中的L2懲罰項(xiàng)不一樣,前者求平方和之后開根號而后者不需要開根號。如果L2范數(shù)大于設(shè)置好的clip_gradient,則求clip_gradient除以L2范數(shù),然后把除好的結(jié)果乘上原來的梯度完成更新。當(dāng)梯度很大的時(shí)候,作為分母的結(jié)果就會很小,那么乘上原來的梯度,整個(gè)值就會變小,從而可以有效地控制梯度的范圍。
另外,觀察公式可知,其實(shí)到底對誰求偏導(dǎo)是看最近的一次是誰作為自變量,就會對誰求,不一定都是對權(quán)重參數(shù)求,也有對y求的時(shí)候。
接著我們用PyTorch來實(shí)操一下反向傳播算法,PyTorch可以實(shí)現(xiàn)自動微分,requires_grad 表示這個(gè)參數(shù)是可學(xué)習(xí)的,這樣我們進(jìn)行BP的時(shí)候,直接用就好。不過默認(rèn)情況下是False,需要我們手動設(shè)置。
import torchx = torch.ones(3,3,requires_grad = True) t = x * x + 2 z = 2 * t + 1 y = z.mean()接下來我們想求y對x的微分,需要注意這種用法只能適用于y是標(biāo)量而非向量
所以當(dāng)y是向量形式的時(shí)候我們可以自己來算,如
x = torch.ones(3,3,requires_grad = True) t = x * x + 2 y = t - 9如果計(jì)算y.backward()會報(bào)錯,因?yàn)槭窍蛄?#xff0c;所以我們需要手動算v,這里就是y對t嘛,全為1,注意v的維度就行。
v = torch.ones(3,3) y.backward(v) print(x.grad)往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機(jī)器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機(jī)器學(xué)習(xí)在線手冊深度學(xué)習(xí)筆記專輯《統(tǒng)計(jì)學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專輯 AI基礎(chǔ)下載機(jī)器學(xué)習(xí)的數(shù)學(xué)基礎(chǔ)專輯黃海廣老師《機(jī)器學(xué)習(xí)課程》視頻課本站qq群851320808,加入微信群請掃碼:
總結(jié)
以上是生活随笔為你收集整理的【机器学习】详解 BackPropagation 反向传播算法!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (建议收藏)相对靠谱的国内大学排行榜
- 下一篇: SVN卸载,修复,等问题:依赖服务或组无