前饋神經網路
在文章《邏輯迴歸到神經網路》(以下簡寫《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演算法原理的程式猿也能輕鬆的寫出來這個數學上不算太簡單的演算法。
更多機器學習的精彩文章,歡迎關注微信訂閱號【夕小瑤的賣萌屋】哦