神經網絡的訓練算法,目前基本上是以Backpropagation (BP) 反向傳播爲主(加上一些變化),NN的訓練是在1986年被提出,但實際上,BP 已經在不一樣領域中被重複發明了數十次了(參見 Griewank (2010)[1])。更加通常性且與應用場景獨立的名稱叫作:反向微分 (reverse-mode differentiation)。本文是看了資料[2]中的介紹,寫的蠻好,本身記錄一下,方便理解。算法
從本質上看,BP 是一種快速求導的技術,能夠做爲一種不僅僅用在深度學習中而且能夠勝任大量數值計算場景的基本的工具。markdown
必須先來說一講計算圖的概念,計算圖出如今Bengio 09年的《Learning Deep Architectures for AI》,
Bengio使用了有向圖結構來描述神經網絡的計算:網絡
整張圖可當作三部分:輸入結點、輸出結點、從輸入到輸出的計算函數。上圖很容易理解,就是output=sin(a*x+b) * x框架
有向無環圖在計算機科學領域處處可見,特別是在函數式程序中。他們與依賴圖(dependency graph)或者調用圖(call graph)緊密相關。一樣他們也是大部分很是流行的深度學習框架背後的核心抽象。函數
下文如下面簡單的例子來描述:工具
假設 a = 2, b = 1,最終表達式的值就是 6。
爲了計算在這幅圖中的偏導數,咱們須要 和式法則(sum rule )和 乘式法則(product rule):學習
下面,在圖中每條邊上都有對應的導數了:
優化
那若是咱們想知道哪些沒有直接相連的節點之間的影響關係呢?假設就看看 e 如何被 a 影響的。若是咱們以 1 的速度改變 a,那麼 c 也是以 1 的速度在改變,致使 e 發生了 2 的速度在改變。所以 e 是以 1 * 2 的關於 a 變化的速度在變化。
而通常的規則就是對一個點到另外一個點的全部的可能的路徑進行求和,每條路徑對應於該路徑中的全部邊的導數之積。所以,爲了得到 e 關於 b 的導數,就採用路徑求和:圖片
這個值就表明着 b 改變的速度經過 c 和 d 影響到 e 的速度。聰明的你應該能夠想到,事情沒有那麼簡單吧?是的,上面例子比較簡單,在稍微複雜例子中,路徑求和法很容易產生路徑爆炸:get
在上面的圖中,從 X 到 Y 有三條路徑,從 Y 到 Z 也有三條。若是咱們但願計算 dZ/dX,那麼就要對 3 * 3 = 9 條路徑進行求和了:
該圖有 9 條路徑,可是在圖更加複雜的時候,路徑數量會指數級地增加。相比於粗暴地對全部的路徑進行求和,更好的方式是進行因式分解:
有了這個因式分解,就出現了高效計算導數的可能——經過在每一個節點上反向合併路徑而非顯式地對全部的路徑求和來大幅提高計算的速度。實際上,兩個算法對每條邊的訪問都只有一次!
前向微分從圖的輸入開始,一步一步到達終點。在每一個節點處,對輸入的路徑進行求和。每一個這樣的路徑都表示輸入影響該節點的一個部分。經過將這些影響加起來,咱們就獲得了輸入影響該節點的所有,也就是關於輸入的導數。
相對的,反向微分是從圖的輸出開始,反向一步一步抵達最開始輸入處。在每一個節點處,會合了全部源於該節點的路徑。
前向微分 跟蹤了輸入如何改變每一個節點的狀況。反向微分 則跟蹤了每一個節點如何影響輸出的狀況。也就是說,前向微分應用操做 d/dX 到每一個節點,而反向微分應用操做 dZ/d 到每一個節點。
讓咱們從新看看剛開始的例子:
咱們能夠從 b 往上使用前向微分。這樣得到了每一個節點關於 b 的導數。(寫在邊上的導數咱們已經提早算高了,這些相對比較容易,只和一條邊的輸入輸出關係有關)
咱們已經計算獲得了 de/db,輸出關於一個輸入 b 的導數。可是若是咱們從 e 往回計算反向微分呢?這會獲得 e 關於每一個節點的導數:
反向微分給出了 e 關於每一個節點的導數,這裏的確是每個節點。咱們獲得了 de/da 和 de/db,e 關於輸入 a 和 b 的導數。(固然中間節點都是包括的),前向微分給了咱們輸出關於某一個輸入的導數,而反向微分則給出了全部的導數。
想象一個擁有百萬個輸入和一個輸出的函數。前向微分須要百萬次遍歷計算圖才能獲得最終的導數,而反向微分僅僅須要遍歷一次就能獲得全部的導數!速度極快!
訓練神經網絡時,咱們將衡量神經網絡表現的代價函數看作是神經網絡參數的函數。咱們但願計算出代價函數關於全部參數的偏導數,從而進行梯度降低(gradient descent)。如今,經常會遇到百萬甚至千萬級的參數的神經網絡。因此,反向微分,也就是 BP,在神經網絡中發揮了關鍵做用!因此,其實BP的本質就是鏈式法則。
(有使用前向微分更加合理的場景麼?固然!由於反向微分獲得一個輸出關於全部輸入的導數,前向微分獲得了全部輸出關於一個輸入的導數。若是遇到了一個有多個輸出的函數,前向微分確定更加快速)
BP 也是一種理解導數在模型中如何流動的工具。在推斷爲什麼某些模型優化很是困難的過程當中,BP 也是特別重要的。典型的例子就是在 Recurrent Neural Network 中理解 vanishing gradient 的緣由。
有的時候,越是有效的算法,原理每每越是簡單。
[1] Who Invented the Reverse Mode of Differentiation?
[2] http://www.jianshu.com/p/0e9eea729476