关于第5周反向传播算法的一些争论与思考
關(guān)于第5周反向傳播算法的一些爭論與思考
第5周介紹了神經(jīng)網(wǎng)絡(luò)的反向傳播算法。由于介紹得比較簡要,很多地方?jīng)]有講透(眾:You can you up!),后來C站論壇里有幾個網(wǎng)友開始爭論其中的公式有點奇怪,究竟是講錯了還是另有原因(最后結(jié)論似乎應(yīng)該是沒講錯)。全程圍觀的耿先生記錄了相關(guān)的一些要點。
背景:
反向傳播算法就是說好比你有一個神經(jīng)網(wǎng)絡(luò),輸入層 -> 隱藏層 -> 輸出層醬紫。我們現(xiàn)在把所有系數(shù)初始化,把訓練集里的 x 都代入到輸入層,經(jīng)過層層計算最后得到一組輸出值。這時候我們就可以和實際的值 y 作比較,計算cost函數(shù)。假設(shè)我們用的是邏輯回歸來研究分類問題,那么cost函數(shù)就應(yīng)該是:
(摘自課程維基頁。下同)
學過前幾周應(yīng)該會知道這個公式是怎么來的。前半部分和前幾周邏輯回歸的cost函數(shù)區(qū)別在于多了一個 K。因為邏輯回歸最后的結(jié)果是一個輸出值,0 到 1 之間。而上述神經(jīng)網(wǎng)絡(luò)最后的結(jié)果是一排值,每一個都是 0 到 1 之間,所以多了一次求和。后半部分其實就是把所有的統(tǒng)統(tǒng)求平方加起來。
cost函數(shù)有了之后我們就可以使用梯度下降法,那么就需要計算梯度gradient。這就要用到反向傳播算法了。簡單來說就是,我們從最后的輸出層的值(可以叫或者叫)開始,計算每一個值的值。這個值描述了當前的計算結(jié)果和實際結(jié)果 y 之間的偏差量error。
對于輸出層,課程告訴我們,就等于。爭論就發(fā)生在這里,我們下面會詳細說是什么爭論。現(xiàn)在先把背景知識介紹完。
對于其它層,則需要從后一層的,倒推前一層的。公式是:
這個公式體現(xiàn)了什么思想呢?我們說了表現(xiàn)了每一個結(jié)點的值與實際值之間的偏差。對于輸出層看似很好理解,減一下得到的就是偏差。不過實際上這里面暗藏玄機。詳見下文(此處為懸念1)。
而對于中間層,所謂“偏差”應(yīng)該這么理解:對于后一層某一個結(jié)點上出現(xiàn)的偏差,前一層的每一個結(jié)點都要承擔一部分責任,所以我們可以把后一層結(jié)點的偏差量按照系數(shù)比例分配給前一層的結(jié)點。同時,前一層的某一個結(jié)點,對后一層的每一個節(jié)點都承擔著責任,那么它的“總責任”就是這些所有的小責任之和。如果你仔細想想這個矩陣乘法的計算過程,會發(fā)現(xiàn)正好就是上面說的這個責任分配與求和的過程。
但是后面乘的 g' 項是從哪里來的呢?我們先不說,詳見下文(此處為懸念2)。我們只要知道,由于這里用的是邏輯回歸,g(z)函數(shù)就是邏輯函數(shù)。g' 是指對它求導。求導之后我們會發(fā)現(xiàn):,而根據(jù)定義又有,所以我們就把上式展開為:
這樣我們就得到了每一層的。之后再用前一層的“每一個”結(jié)點的值 a,乘以后一層的“每一個”結(jié)點的,就得到了一個矩陣。寫成公式是。這個矩陣的規(guī)模和前后兩層之間的系數(shù)矩陣是一致的,因為它們都是由前一層的每一個結(jié)點指向后一層的每一個結(jié)點。這個矩陣有什么意義呢?實際上,前一層的結(jié)點 i 的值,乘以后一層結(jié)點 j 的值,得到的就是cost函數(shù)對于的偏微分。為什么呢?詳見下文(懸念3)。總之,這其實就是我們要求的梯度。
注意,上面這部分(從“簡單來說就是……”那句話往后)是針對“一條”輸入數(shù)據(jù)所進行的計算。而我們的訓練集里通常有很多條,比如有 m 條數(shù)據(jù)。我們針對每一條都進行上述計算,最后把每一條的都累加起來再除以 m,得到的就是我們真正需要的梯度矩陣。然后就可以使用梯度下降法尋找最優(yōu)了。
爭議:
在C站課程論壇上,有人發(fā)了一個帖子,指出輸出層的計算公式有問題。課程給出的公式是:
Andrew Ng在這里并沒有詳細解釋這個計算公式是怎么來的。實際上它是cost函數(shù)求導求出來的,具體求法詳見下文(懸念4)。該貼樓主和樓主的小伙伴認為Andrew Ng犯了一個錯誤,誤將線性回歸的cost函數(shù)用在了邏輯回歸計算中。因為邏輯回歸的cost函數(shù)是長最上面那個鬼樣子。為了便于看清楚我們將它簡化一下(忽略求和,忽略后半部分項):
對它求導后得到的應(yīng)該是:
(注意。)
而只有線性回歸的cost函數(shù):
求導之后才能得到:
幾位TA覺得他們說的好有道理無法反駁,只能不斷地說我信任Prof Ng男神是不會錯的!最后還是樓主的小伙伴自己發(fā)了個帖子指出了真正的問題出在哪里。
原來還是他們理解錯了公式。并非簡單地對cost函數(shù)求導就可以。它真正的計算方法是:詳見下文(眾:你去死吧!)……
真相:
問題的焦點集中在了真正的計算公式上面。維基百科“反向傳播算法”頁面給出了這個過程。我們下面來看看到底是怎么求的。我們之前留下的懸念1、2、3、4,也將一次性解決。
讓我們回到我們的初心。這一切究竟是為了什么?啊!是為了求cost函數(shù)對于每一個的偏微分,也就是求:
(其中分母上的那坨東東是指:第 l 層的結(jié)點 i,指向其下一層也就是 l+1 層的結(jié)點 j 的系數(shù)。)
(評論中有人指出這里似乎 i 和 j 的意義弄反了。我查了一下似乎是反了,表示前一層結(jié)點的字母應(yīng)該寫在后面。如果第 l 層是結(jié)點 i,第 l+1 層是結(jié)點 j,的下標應(yīng)該是 j,i 這樣子。如果這里反了的話上面背景部分的倒數(shù)第二段估計也弄反了。如果你需要參考這篇文章里的公式,請留意一下這個問題。我暫時先不改了。)
再回顧一下我們計算輸出值時的一些定義:,,。
為了使用這些定義,我們可以將上面的偏微分式子展開為:
(此處使用技能:鏈式法則x2)
把求一次偏微分變成了求三次偏微分。
右邊這三項,我們先看最后一項。根據(jù)定義我們知道:
所以:
JOB DONE...........33%
順便說一句,右邊前兩項的乘積,就是課程里引入的值!這就回答了懸念 3 提出的問題:為什么得到后一層的值之后,要乘以前一層的 a 值來得到偏微分?答案是:因為它們分別是偏微分式子展開后的兩個乘數(shù)。
接下來我們看第二項:這不就是對sigmoid函數(shù)求導嗎?之前我們遇到過的g'(z),它的出處原來是這里!
我們經(jīng)過計算后會得到這樣一個式子:
恰好,算出來也是這個式子,所以我們就用后面這個更好算的式子來計算了。這就是計算公式的后半部分,的來源。
JOB DONE...........67%
現(xiàn)在來到第一項偏微分。對于中間層的結(jié)點,這個偏微分并不好算。(也能算,需要繼續(xù)使用鏈式法則展開成更多的項!最后算出來就是上面計算公式的前半部分。)但是我們只想知道關(guān)于最后輸出層的情況。那就簡單多了!上面爭議部分中,那位樓主的小伙伴已經(jīng)給出了cost函數(shù)對于輸出層求偏微分的結(jié)果:
JOB DONE...........100%
那么說到底輸出層的到底等于多少?
等于前兩項的乘積:
原來地球是這個樣子滴……
結(jié)論:
Andrew Ng給的公式?jīng)]有錯。他只是把復(fù)雜的推倒,不是,推導過程省略了。但是這樣一來容易產(chǎn)生誤解。很多人以為輸出層的偏差量就是計算值減實際值這么簡單,其實是碰巧才這么簡單的。還有很多人說為什么這個值和很多別的網(wǎng)站,包括維基百科上說的不一樣啊?因為很多別的網(wǎng)站包括維基百科,cost函數(shù)用的是線性回歸的那種,。它的偏微分就和邏輯回歸的cost函數(shù)有差別了。具體地說,就差在分母的那一項上。
tl;nr:男神沒搞錯。微積分很復(fù)雜。而貓咪依舊是可愛的。
總結(jié)
以上是生活随笔為你收集整理的关于第5周反向传播算法的一些争论与思考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从程序员的角度分析微信小程序
- 下一篇: 今年美国广告程序化购买支出将超252亿美