一、反向傳播的由來
在我們開始DL的研究之前,需要把ANN—人工神經元網絡以及bp算法做一個簡單解釋。
關於ANN的結構,我不再多說,網上有大量的學習資料,主要就是搞清一些名詞:
輸入層/輸入神經元,輸出層/輸出神經元,隱層/隱層神經元,權值,偏置,激活函數
接下來我們需要知道ANN是怎么訓練的,假設ANN網絡已經搭建好了,在所有應用問題中(不管是網絡結構,訓練手段如何變化)我們的目標是不會變的,那就是網絡的權值和偏置最終都變成一個最好的值,這個值可以讓我們由輸入可以得到理想的輸出,於是問題就變成了y=f(x,w,b)(x是輸入,w是權值,b為偏置,所有這些量都可以有多個,比如多個x1,x2,x3……最后f()就好比我們的網絡它一定可以用一個函數來表示,我們不需要知道f(x)具體是怎樣的函數,從小我們就認為只要是函數就一定要是可表示的,像f(x)=sin(x)一樣,但是請擯棄這樣的錯誤觀念,我們只需要知道一系列的w和b決定了一個函數f(x),這個函數讓我們由輸入可以計算出合理的y)
最后的目標就變成了嘗試不同的w,b值,使得最后的y=f(x)無限接近我們希望得到的值t
但是這個問題依然很復雜,我們把它簡化一下,讓(y-t)^2的值盡可能的小。於是原先的問題化為了C(w,b)=(f(x,w,b)-t)^2取到一個盡可能小的值。這個問題不是一個困難的問題,不論函數如何復雜,如果C降低到了一個無法再降低的值,那么就取到了最小值(假設我們不考慮局部最小的情況)
如何下降?數學告訴我們對於一個多變量的函數f(a,b,c,d,……)而言,我們可以求得一個向量,它稱作該函數的梯度,要注意的是,梯度是一個方向向量,它表示這個函數在該點變化率最大的方向(這個定理不詳細解釋了,可以在高等數學教材上找到)於是C(w,b)的變化量ΔC就可以表示成
其中
是該點上的微小變化,我們可以隨意指定這些微小變化,只需要保證ΔC<0就可以了,但是為了更快的下降,我們為何不選在梯度方向上做變化呢?
事實上,梯度下降的思想就是這樣考慮的,我們使得從而保證C一直遞減,而對於w來說只要每次更新
即可。
ok,到這里,似乎所有的問題都解決了,讓我們重新整理一下思緒,我們將問題轉化了很多步:
網絡權值偏置更新問題 ==> f(x,w,b)的結果逼近t ==> C(w,b)=(f(x,w,b)-t)^2取極小值問題 ==> C(w,b)按梯度下降問題 ==>取到極小值,網絡達到最優
千萬別忘了一點!!推導基於一個前提:我們已經提前知道了當前點的梯度。然而事實並非如此!!
這個問題困擾了NN研究者多年,1969年M.Minsky和S.Papert所著的《感知機》一書出版,它對單層神經網絡進行了深入分析,並且從數學上證明了這種網絡功能有限,甚至不能解決象"異或"這樣的簡單邏輯運算問題。同時,他們還發現有許多模式是不能用單層網絡訓練的,而對於多層網絡則沒有行之有效的低復雜度算法,最后他們甚至認為神經元網絡無法處理非線性問題。然而於1974年,Paul Werbos首次給出了如何訓練一般網絡的學習算法—back propagation。這個算法可以高效的計算每一次迭代過程中的梯度,讓以上我們的推導得以實現!!
不巧的是,在當時整個人工神經網絡社群中無人知曉Paul所提出的學習算法。直到80年代中期,BP算法才重新被David Rumelhart、Geoffrey Hinton及Ronald Williams、David Parker和Yann LeCun獨立發現,並獲得了廣泛的注意,引起了人工神經網絡領域研究的第二次熱潮。
二、原理的引入
上面已經提到,所謂反向傳播,就是計算梯度的方法。對於反向傳播,先不急着介紹它的原理,很多文章直接引入公式,反而使得我們很難去理解。這里先引入知乎上某位大神的回答。
來源:知乎https://www.zhihu.com/question/27239198?rf=24827633
假設輸入a=2,b=1,在這種情況下,我們很容易求出相鄰節點之間的偏導關系
利用鏈式法則:
以及
的值等於從a到e的路徑上的偏導值的乘積,而
的值等於從b到e的路徑1(b-c-e)上的偏導值的乘積加上路徑2(b-d-e)上的偏導值的乘積。也就是說,對於上層節點p和下層節點q,要求得
,需要找到從q節點到p節點的所有路徑,並且對每條路徑,求得該路徑上的所有偏導數之乘積,然后將所有路徑的 “乘積” 累加起來才能得到
的值。
這種情況下偏導很容易求得,因為我們已經知道網絡的函數關系式,e=(a+b)*(b+1),這是一個沒有權值干預,已知輸入與輸出之間關系的網絡。實際當中我們只是知道e與輸出之間的關系,就是上面說的C=(y-t)^2,而且會有成千上萬的權值和偏置干預求導的過程。那么換個思路,能不能求輸出對結果的偏導呢?
再利用上圖的關系。節點c對e偏導2並將結果堆放起來,節點d對e偏導3並將結果堆放起來,至此第二層完畢,求出各節點總堆放量並繼續向下一層發送。節點c向a發送2*1並對堆放起來,節點c向b發送2*1並堆放起來,節點d向b發送3*1並堆放起來,至此第三層完畢,節點a堆放起來的量為2,節點b堆放起來的量為2*1+3*1=5, 即頂點e對b的偏導數為5。簡要的概括,就是從最上層的節點e開始,以層為單位進行處理。對於e的下一層的所有子節點,將1乘以e到某個節點路徑上的偏導值,並將結果“堆放”在該子節點中。等e所在的層按照這樣傳播完畢后,第二層的每一個節點都“堆放"些值,然后我們針對每個節點,把它里面所有“堆放”的值求和,就得到了頂點e對該節點的偏導。然后將這些第二層的節點各自作為起始頂點,初始值設為頂點e對它們的偏導值,以"層"為單位重復上述傳播過程,即可求出頂點e對每一層節點的偏導數。
三、一個很好的例子
假設,你有這樣一個網絡層:
第一層是輸入層,包含兩個神經元i1,i2,和截距項b1;第二層是隱含層,包含兩個神經元h1,h2和截距項b2,第三層是輸出o1,o2,每條線上標的wi是層與層之間連接的權重,激活函數我們默認為sigmoid函數。
現在對他們賦上初值,如下圖:
其中,輸入數據 i1=0.05,i2=0.10;
輸出數據 o1=0.01,o2=0.99;
初始權重 w1=0.15,w2=0.20,w3=0.25,w4=0.30;
w5=0.40,w6=0.45,w7=0.50,w8=0.88
目標:給出輸入數據i1,i2(0.05和0.10),使輸出盡可能與原始輸出o1,o2(0.01和0.99)接近。
Step 1 前向傳播
1.輸入層---->隱含層:
計算神經元h1的輸入加權和:
神經元h1的輸出o1:(此處用到激活函數為sigmoid函數):
同理,可計算出神經元h2的輸出o2:
2.隱含層---->輸出層:
計算輸出層神經元o1和o2的值:
這樣前向傳播的過程就結束了,我們得到輸出值為[0.75136079 , 0.772928465],與實際值[0.01 , 0.99]相差還很遠,現在我們對誤差進行反向傳播,更新權值,重新計算輸出。
Step 2 反向傳播
1.計算總誤差
總誤差:(square error)
但是有兩個輸出,所以分別計算o1和o2的誤差,總誤差為兩者之和:
2.隱含層---->輸出層的權值更新:
以權重參數w5為例,如果我們想知道w5對整體誤差產生了多少影響,可以用整體誤差對w5求偏導求出:(鏈式法則)
下面的圖可以更直觀的看清楚誤差是怎樣反向傳播的:



現在我們來分別計算每個式子的值:
計算:
計算:
(這一步實際上就是對sigmoid函數求導,比較簡單,可以自己推導一下)
計算:
最后三者相乘:
這樣我們就計算出整體誤差E(total)對w5的偏導值。
回過頭來再看看上面的公式,我們發現:
為了表達方便,用來表示輸出層的誤差:
因此,整體誤差E(total)對w5的偏導公式可以寫成:
如果輸出層誤差計為負的話,也可以寫成:
最后我們來更新w5的值:
(其中,是學習速率,這里我們取0.5)
同理,可更新w6,w7,w8:
3.隱含層---->隱含層的權值更新:
方法其實與上面說的差不多,但是有個地方需要變一下,在上文計算總誤差對w5的偏導時,是從out(o1)---->net(o1)---->w5,但是在隱含層之間的權值更新時,是out(h1)---->net(h1)---->w1,而out(h1)會接受E(o1)和E(o2)兩個地方傳來的誤差,所以這個地方兩個都要計算。
計算:
先計算:
同理,計算出:
兩者相加得到總值:
再計算:
再計算:
最后,三者相乘:
為了簡化公式,用sigma(h1)表示隱含層單元h1的誤差:
最后,更新w1的權值:
同理,額可更新w2,w3,w4的權值:
這樣誤差反向傳播法就完成了,最后我們再把更新的權值重新計算,不停地迭代,在這個例子中第一次迭代之后,總誤差E(total)由0.298371109下降至0.291027924。迭代10000次后,總誤差為0.000035085,輸出為[0.015912196,0.984065734](原輸入為[0.01,0.99]),證明效果還是不錯的
四、最一般的情況


























以上4個方程中,第一個方程其實不難理解,就是求輸出對估價函數C的偏導。
唯一比較困難的,就是第二個方程,它給出了根據下一層的錯誤量δl+1計算δl的等式。為證明該等式,我們先依據δkl+1=∂C/∂zkl+1重新表達下等式δlj =∂C/∂zlj。這里可以應用鏈式法則:
在最后一行,我們互換了下表達式右側的兩項,並取代了 δkl+1的定義。為了對最后一行的第一項求值,注意:
作微分,我們得到
代回 (42) 我們得到
這就是以分量形式呈現的 (BP2)。后兩式在完成了BP2證明之后就不太難了,留給讀者來證明。
四、證明
1. 變量定義


































2. 代價函數










3. 公式及其推導



















4. 反向傳播算法偽代碼
- 輸入訓練集
- 對於訓練集中的每個樣本x,設置輸入層(Input layer)對應的激活值
:
- 前向傳播:


- 計算輸出層產生的錯誤:

- 反向傳播錯誤:

- 使用梯度下降(gradient descent),訓練參數:

