史上最清楚的BP算法详解
前饋神經網絡
在文章《邏輯回歸到神經網絡》(以下簡寫《LR到NN》)中,小夕為大家描述了一個從邏輯回歸延伸到神經網絡的過程。在《一般化機器學習與神經網絡》中,小夕闡述了神經網絡的一般性。這一篇會完全進入神經網絡的狀態,闡述神經網絡的特殊性。
其實在《LR到NN》中的這張簡單的圖,就是本文要講的前饋神經網絡(feed-forward neural network)。
?
?
可以看到,這種簡單粗暴的連法,恰恰就是神經網絡最經典的模型。即隱含層的每個單元(神經元)均只接受前一層(對于只有一個隱含層的前饋網絡,前一層即輸入層)的輸出作為輸入,并輸出結果到后一層(對于只有一個隱含層的前饋網絡,后一層即輸出層)。將這種神經網絡看成數據結構中的“圖”的話,那就是一個“有向無環圖”(即前饋網絡中是不存在反饋的)。
這里的邊,即單元與單元之間連接的強度,也即權重。設想一下,當兩個單元之間的權重為0時,一個單元的輸出就無法再通過這條邊傳遞給另一個單元了,即這兩個單元之間斷開連接了(不存在這條邊了),因此神經網絡模型中的模型參數不僅僅是個數字了,由于這張基于生物學中的神經系統的模型可視化圖的存在,神經網絡模型中的參數還代表著兩個神經元之間的連接強度。
在《一般化機器學習與神經網絡》中,小夕講過了,所謂的前向算法,就是計算了一下模型的假設函數而已,只不過計算的過程可視化出來后就是一個沿著神經網絡“向前推進”的樣子,因此起了個名字而已。這里就不再贅述這個俗俗的假算法啦。
根據機器學習框架,假設函數有了,我們還需要考慮什么呢?當然是如何得到這個假設函數啦~也就是如何訓練神經網絡這個一般而特殊的機器學習模型(即學習模型參數)。
石器時代
假設你是一個完全不懂數學的生物學家(雖然學生物的數學也很厲害的,吧),你覺得從生物學的角度來看(將模型參數看作神經元之間的連接強度),這個神經網絡訓練好之后應該是什么樣子的呢?
回想一下高中生物,如果兩個神經元緊緊相連,那么一個神經元的興奮必然導致與之相連的神經元的興奮。如果經過無數次實驗,我們發現對于神經元A和神經元B,只要A興奮,那么B一定興奮,那么就說明A與B之間肯定連接非常緊密(就像一條繩子的螞蚱,一個跳起來肯定把另一個帶起來),也就是說A到B的連接強度非常大!也就是說,A到B這個模型參數的值肯定很大。
將這個生物學思想往數學上靠一下,那就是“如果神經元A的激活帶來B的激活,就代表A與B具有相關性,因此A與B之間的連接權重應該被加強,即應增大模型參數(下標BA代表從A出發,到達B的有向邊)”。
這個思想叫什么呢?叫“Hebb規則”,這個思想是神經網絡的學習算法的最本質,也是最原始的思想。
那么如何去實現這個思想呢?
青銅時代
設想一下,我們的網絡到達了這么一種狀態:
?
顯然,模型犯錯了!輸出單元(輸出層在這里只有一個單元)應該是1,結果預測的是0!也就是應該興奮,實際在睡覺!而根據Hebb規則,我們應該讓輸出單元加強與那些興奮的神經元的連接,也就是增大與“隱含層輸出為1(專業說法叫被激活)的神經元”的連接!減弱與“隱含層輸出為0(未激活)的神經元”的連接!
再想一下,“隱單元未激活/輸出為0”代表著什么?
還記得《邏輯回歸到神經網絡》中放大的這個隱單元的圖嗎?
?
隱單元的核心就是激活函數,比如sigmoid、tanh等。如下sigmoid:
?
因此隱單元輸出為0時,也就是未激活時,就意味著隱單元的輸入為負值!
所以,為了迎合Hebb規則,應該讓未激活的神經元減小權重,激活的神經元增加權重,那么我們可以直接讓權重加上隱單元的輸入啊:
即對于全部的隱單元:w=w+a。(注:a為隱單元的輸入,未激活的神經元的a為負,激活的為正)
而對于如下這種情況,也就是應該輸出0,實際輸出了1的情況:
?
?
通過跟前面一樣的推理我們發現,只要讓w的更新方式與前面相反,即:對于全部的隱單元:w=w-a。(注:a為隱單元的輸入,未激活的神經元的a為負,激活的為正)
那么有沒有辦法將上面兩種情況合起來表示呢?
機智的你應該想到了,那就是:
w=w+(真實值-預測值)*a
對啊,用這條通用的規則,就可以反復的更新隱藏層到輸出層的權重了~這個規則叫什么呢?這就是1986年認知心理學家Rumellhart等人提出的δ學習規則,也叫廣義Hebb規則,這是對神經網絡學習算法的Hebb思想的直接實現!
等等,有沒有覺得似曾相識呢?趕緊翻開書,看看BP算法的權重更新公式!有沒有發現BP中的權重更新公式與這個規則所表達的意思驚人的相似!
相似就對了~
鐵器時代
想一想,在廣義Hebb規則中,我們做了一些簡化:
首先,權重更新的方向很明確,但是更新的步長我們是直接用了隱單元的輸入a,而沒有證明這個a是最合理的步長。其次,我們這里直接用真實值減去預測值,也是很啟發式的做法。
那么顯然這個廣義Hebb規則在數學上極有可能是非最優的,畢竟這是一個啟發式的(即拍腦袋的)算法。那么如何得到最優的做法呢?那就是從這個規則的目的著手去提出更上層的理論!
廣義Hebb規則的目的是什么呢?
這個規則的直接目的是讓最終的輸出逼近真實輸出,也就是減小模型輸出與真實輸出之間的誤差。具體做法是讓每個隱單元的權重個性化修改,來向著使誤差減小的方向移動。
等等!再重復一遍,具體做法是讓每個隱單元的權重個性化修改,來向著使誤差減小的方向移動。
再再重復一遍!具體做法是讓每個隱單元的權重個性化修改,來向著使誤差減小的方向移動!
所以我們可以怎樣做?如果有一個函數可以直接描述這個誤差!(這不就是損失函數做的事兒嗎!)那么!以權重為誤差的自變量,使誤差減小的方向不就是權重的負梯度方向嗎。那讓權重沿著這個方向移動不久好了嗎?(這不就是梯度下降法嗎!)
?
如圖,自變量(x軸)是權重,因變量(y軸)是誤差!顯然使誤差減小的方向就是權重的負梯度方向啊~
所以!求出此時權重的負梯度(即此時每個隱單元的權重的導數!)!然后讓權重向這個方向移動一定的步長!反復這個移動的過程!直到誤差最小,即訓練完成!得到最優的權重!
所以說這是什么?這就是梯度下降法呀~同時,這還是BP算法對隱含層與輸出層連接權重的更新方式啊!
那么如何更新輸入層到隱含層的權重呢?
一樣的呀,數學思想都這么清晰了~誤差依然是誤差,只需要將自變量換成輸入層到隱含層的權重,不就可以啦~其他的完全照舊啊。
只不過,損失函數是“間接包含”輸入層到隱含層的權重的,因此在求此時的負梯度時,要進行鏈式求導~也就是下面這個爛大街的推理過程:
?
?
?
這個推理過程摘自http://blog.csdn.net/lu597203933/article/details/46575803,有興趣的可以去看看,反正哪里都能找到這個推導過程~數學好的一眼就看懂了,不太好的就隨便找個講BP算法的書或者帖子啦,這是真正的爛大街推理過程。。。因此,各層權重的負梯度利用上面的鏈式求導法則就很輕松的求出來了,然后w=w-α*負梯度,就可以啦~其中,α是步長~
看,源于訓練神經網絡的最na?ve的Hebb思想,為了實現這個思想而提出了δ算法,用數學去描述δ算法的本質目標,得出通過引入損失函數并(鏈式求導)求解負梯度來更新權重的過程,即誤差反向傳播算法(BackPropagation,簡稱BP算法)。
╮(╯▽╰)╭
只不過在神經網絡中可視化一下,看起來就像一個人們定義的誤差從模型輸出層向輸入層傳播而已啦,然后起了個形象的名字叫所謂的誤差反向傳播算法。
不過,人們抽象出來的這個前向與反向算法的概念還是有更多原因的,一是可以幫助人們理解,使其可以從生物學模型上得到解釋,進而以這種思想變形出其他形式的前向與反向傳播算法來描述或訓練更復雜的神經網絡;另一方面也是給我們程序猿(喵)們提供了一種簡潔無腦的編程模型,使得哪怕不懂鏈式求導等BP算法原理的程序猿也能輕松的寫出來這個數學上不算太簡單的算法。
總結
以上是生活随笔為你收集整理的史上最清楚的BP算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解RPC远程调用和消息队列MQ的区别
- 下一篇: 美团点评容器平台HULK的调度系统