關于反向傳播算法,很早之前就了解,但是關于細節問題一直未能了解,看了這篇翻譯的文章寫的很好
原文:http://blog.csdn.net/shijing_0214/article/details/51923547
Backpropagation算法是目前絕大多數神經網絡在優化參數時用到的算法,具有快速友善容易實作的優點。那麼它是如何實作的呢?
首先看一張典型神經網絡結構圖:

上圖是一個包含了輸入層L1、一個 隐含層L2和輸出層L3的簡單神經網絡,它的處理流程為根據輸入層的input以及相應的權重和偏置(圖中黑色帶箭頭的邊),通過隐含層的加工,最終将結果映射到輸出層得到結果。模型可以抽象表示為 y=f(x),x,y分别表示輸入輸出向量,在分類問題中,y表示相應的類别 ,顯然這是一個判别模型。
由神經網絡的處理過程,想要得到輸出 y ,我們必須知道上圖中每條邊的參數值,這也是神經網絡中最重要的部分。在神經網絡中是通過疊代的方法來計算這些參數的,具體來講就是,首先初始化這些參數,通過神經網絡的前向傳導過程計算得到輸出 y ,這些值與真實值存在着誤差,不妨設累計誤差函數為 err(x) ,然後利用梯度法極小化 err(x) 來更新參數,直至誤內插補點達到要求停止計算。在更新參數這一過程中我們就用到了大名鼎鼎的反向傳播算法。
為了能清楚說明神經網絡的傳播算法,我們取上圖中的一條路徑來做說明,不失一般性,假設路徑為:
圖中的邊表示偏導數,如 α=∂Y∂X
想要知道輸入 X 對輸出 Z 的影響,我們可以用偏導數 ∂Z∂X=∂Z∂Y⋅∂Y∂X ,即:
∂Z∂X=αδ+αϵ+αζ+βδ+βϵ+βζ+γδ+γϵ+γζ⋯式子1
如果直接使用鍊式法則進行求導會出現一個問題,當路徑數目增加時,該式子中的子項數目會呈指數增長,考慮到這種情況,我們把上式右側進行合并,得到:
∂Z∂X=(α+β+γ)(δ+ϵ+ζ)⋯式子2
合并後的式子是不是非常清晰,關鍵是與式子1相比,隻需要進行一次乘法就可以得出結果,大大提高了運算速度。
現在的問題是,對于式子2,應該如何實作?我們知道,假設一條 北京→鄭州→武漢 的路徑,我們可以先分析北京至鄭州,再分析鄭州至武漢;也可以先分析鄭州至武漢,再分析北京至鄭州。同理,根據計算方向的不同,可以分為正向微分與反向微分。我們先看針對上圖的正向微分算法:
可以看到,正向微分算法根據路徑的傳播方向,依次計算路徑中的各結點對輸入 X 的偏導數,結果中保留了輸入對各結點的影響。
我們再看下反向微分算法:
可以看到,該算法從後向前進行計算,結果中保留了路徑中各結點對輸出的影響。
這裡就有一個問題了,既然正向反向都可以實作式子2的計算,那麼我們應該選擇哪個算法來實作呢?答案是反向微分算法,為什麼呢?
首先我們看一個計算式子 e=(a+b)∗(b+1) 的圖模型:
其中, c,d 表示中間結果,邊的方向表示一個結點是另一個結點的輸入。
假設輸入變量 a=2,b=1 時,圖中各結點的偏導計算結果如下:
利用正向微分算法,我們得到關于變量b的偏導計算結果如下:
而利用反向微分算法,我們得到的偏導計算結果如下:
對比兩張圖,看到差別了麼?
可以看出,反向微分算法保留了所有變量包括中間變量對結果 e 的影響。若 e 為誤差函數,則對圖進行一次計算,則可以得出所有結點對 e 的影響,也就是梯度值,下一步就可以利用這些梯度值來更新邊的權重;而正向微分算法得到的結果是隻保留了一個輸入變量對誤差 e 的影響,顯然,想要獲得多個變量對 e 的影響,我們就需要進行多次計算,是以正向微分算法在效率上明顯不如反向微分,這也是我們選擇反向微分算法的原因。
參考:
Calculus on Computational Graphs: Backpropagation
https://zhuanlan.zhihu.com/p/21407711?refer=intelligentunit
http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html