BP 反向傳播

反向傳播是使訓練深度學習模型能夠計算自如的關鍵算法。對於現代神經網絡,相對於傳統的執行,它可以使基於梯度下降的訓練相對於傳統的執行快一千萬倍。這就是一個模型需要一個星期訓練和花費20萬年的區別。

除了在深度學習中的使用,反向傳播是許多其他領域的強大計算工具,從天氣預報到分析數值穩定性 -它只是以不同的名字出現。實際上,該算法在不同領域已被重新發明了數十次。一般,作爲獨立的應用程序,名稱是“反向模式求導”。

從根本上說,這是一種快速計算導數的技術。這不僅僅是在深度學習中,而且在各種各樣的數值計算環境中,這是很有必要掌握的一項技巧。

計算圖

計算圖是考慮數學表達式的好方法。例如,對於表達式e =(a + b)*(b + 1)。有三個操作:兩個加法和一個乘法。爲了幫助我們討論這個問題,我們來引入兩個中間變量c和d,以便每個函數的輸出都有一個變量。我們現在有:

c=a+bd=b+1e=c∗d

要創建一個計算圖,我們將這些操作和輸入變量一起放入節點中。當一個節點的值是另一個節點的輸入時,箭頭從一個指向另一個。

這種圖形一直在計算機科學中出現,特別是在討論函數式編程時。它們與依賴關係圖和調用圖的概念非常密切相關。,同時也是Theano的熱門深度學習框架背後的核心抽象。

我們可以通過將輸入變量設置爲某些值並通過圖形向上計算節點來評估表達式。例如,我們設置a = 2和b = 1:

表達式計算結果爲6。

計算圖上的導數

如果想要理解計算圖中的導數,關鍵是理解在邊緣上的導數。如果a直接影響c,那麼我們想知道它怎樣影響c。如果a有一點改變,相應的c怎麼變化?我們把這叫做c相對於a的偏導數。

爲了評估該圖中的偏導數,我們需要導數運算的加法規則和乘法規則:

下圖中,每個邊上都有導數:

如果我們想了解沒有直接連接的節點之間如何影響?我們考慮一下e如何受到影響。如果我們以1的速度改變a,c也以1的速度變化。然後,以1的速度變化的c導致e以2的速度改變。所以e以1 * 2的速率變化,相對於a來說。

一般規則是將從一個節點到另一個節點的所有可能路徑相加,將路徑的每個邊緣的導數相乘在一起。例如,得到e相對於b的偏導數:

這說明b如何通過c影響e,以及如何通過d影響它。

這種一般的“對所有路徑求和”的規則只是對多變量鏈式法則的另一種思考方式。

因式分解路徑

對路徑求和的規則在遇到相關的路徑呈爆炸式增長時會存在問題。

在上圖中,從X到Y有三條路徑,還有從Y到Z的三條路徑。如果要通過求和所有路徑得到導數∂Z/∂X,我們需要求和3 * 3 = 9條路徑:

以上只有九條路徑,但是隨着圖形變得越來越複雜,路徑的數量增長將變得非常多。

對路徑上的結果進行求和後對它們進行因式分解:

在這裏引入“正向模式求導”和“反向模式求導”,它們是通過分解路徑求和來進行有效計算的算法。不是明確地對所有路徑求和,它們通過將路徑合併在每個節點上來更有效地計算。事實上,這兩種算法都會觸摸每個邊緣一次!

正向模式求導從圖形的輸入開始,向着最後方向移動。在每個節點,它將所有進入的路徑相加。這些路徑中的每一個表示輸入影響該節點的一種方式。通過添加它們,我們得到節點受輸入影響的總體方式,它就是導數。

儘管從圖形上你可能想不到它的樣子,但是如果你上了微積分課程,它與你所學到的東西很相似。

另一方面,反向模式區分從圖形的輸出開始,並朝向開始移動。在每個節點,它合併起始於該節點的所有路徑。

前向模式求導跟蹤一個輸入如何影響每個節點。反向模式求導跟蹤每個節點如何影響一個輸出。也就是說,前向模式求導將運算符∂/∂X應用於每個節點,而反向模式求導則將運算符∂Z/∂應用於每個節點。

計算上的優勢

此時,你可能會想知道爲什麼有人都會關心反向模式求導。與正向模式求導相比,這看起來像一個奇怪的方式做同樣的事情。這樣做有什麼優勢嗎?

我們再來看一下之前的例子:

figure1

我們可以使用前向模式求導。下面給出了每個節點相對於b的導數:

我們已經計算出∂e/∂b,我們的輸出相對於一個輸入的導數。

如果我們從 e向下進行反向模式求導呢?下面給出了我們關於每個節點的e的導數:

當我說反向模式求導給出了我們e相對於每個節點的導數,我說的確實是每一個節點。我們得到∂e/∂a和∂e/∂b,e相對於兩個輸入的導數。前向模式求導給出了我們輸出相對於單個輸入的導數,但反向模式求導給了我們所有的導數。

對於這個圖表,這僅僅是兩個因子的加速,但是想象一個具有一百萬個輸入和一個輸出的函數。正向模式求導需要我們通過數百萬次計算得到導數。反向模式求導可以一下子全部得到他們!一次一百萬的加速是相當不錯的!

在神經網絡中的應用

當訓練神經網絡時,我們考慮成本(一個描述神經網絡表現如何的值)作爲參數(描述神經網絡行爲的數字)的函數。我們要計算相對於所有參數的成本的導數,用於梯度下降。現在,神經網絡中通常有數百萬甚至數千萬個參數。因此,在神經網絡背景下稱爲反向傳播的反向模式求導給了我們巨大的提速!

這裏先直觀理解多層神經網絡的訓練:

機器學習可以看做是數理統計的一個應用,在數理統計中一個常見的任務就是擬合,也就是給定一些樣本點,用合適的曲線揭示這些樣本點隨着自變量的變化關係。

深度學習同樣也是爲了這個目的,只不過此時,樣本點不再限定爲(x, y)點對,而可以是由向量、矩陣等等組成的廣義點對(X,Y)。而此時,(X,Y)之間的關係也變得十分複雜,不太可能用一個簡單函數表示。然而,人們發現可以用多層神經網絡來表示這樣的關係,而多層神經網絡的本質就是一個多層複合的函數。借用網上找到的一幅圖[1],來直觀描繪一下這種複合關係。

其對應的表達式如下:

上面式中的Wij就是相鄰兩層神經元之間的權值,它們就是深度學習需要學習的參數,也就相當於直線擬合y=k*x+b中的待求參數k和b。

和直線擬合一樣,深度學習的訓練也有一個目標函數,這個目標函數定義了什麼樣的參數纔算一組“好參數”,不過在機器學習中,一般是採用成本函數(cost function),然後,訓練目標就是通過調整每一個權值Wij來使得cost達到最小。cost函數也可以看成是由所有待求權值Wij爲自變量的複合函數,而且基本上是非凸的,即含有許多局部最小值。但實際中發現,採用我們常用的梯度下降法就可以有效的求解最小化cost函數的問題。

梯度下降法需要給定一個初始點,並求出該點的梯度向量,然後以負梯度方向爲搜索方向,以一定的步長進行搜索,從而確定下一個迭代點,再計算該新的梯度方向,如此重複直到cost收斂。那麼如何計算梯度呢?

假設我們把cost函數表示爲

那麼它的梯度向量[2]就等於

其中eij表示正交單位向量。爲此,我們需求出cost函數H對每一個權值Wij的偏導數。而BP算法正是用來求解這種多層複合函數的所有變量的偏導數的利器

回到之前的例子e = c * d ,大家也許已經注意到,正向求導是十分冗餘的,因爲很多路徑被重複訪問了。比如圖figure1中,a-c-e和b-c-e就都走了路徑c-e。對於權值動則數萬的深度模型中的神經網絡,這樣的冗餘所導致的計算量是相當大的。

同樣是利用鏈式法則,BP算法則機智地避開了這種冗餘,它對於每一個路徑只訪問一次就能求頂點對所有下層節點的偏導值。正如反向傳播(BP)算法的名字說的那樣,BP算法是反向(自上往下)來尋找路徑的。

從最上層的節點e開始,初始值爲1,以層爲單位進行處理。對於e的下一層的所有子節點,將1乘以e到某個節點路徑上的偏導值,並將結果“堆放”在該子節點中。等e所在的層按照這樣傳播完畢後,第二層的每一個節點都“堆放"些值,然後我們針對每個節點,把它裏面所有“堆放”的值求和,就得到了頂點e對該節點的偏導。然後將這些第二層的節點各自作爲起始頂點,初始值設爲頂點e對它們的偏導值,以"層"爲單位重複上述傳播過程,即可求出頂點e對每一層節點的偏導數。

以圖figure1爲例,節點c接受e發送的12並堆放起來,節點d接受e發送的13並堆放起來,至此第二層完畢,求出各節點總堆放量並繼續向下一層發送。節點c向a發送21並對堆放起來,節點c向b發送21並堆放起來,節點d向b發送31並堆放起來,至此第三層完畢,節點a堆放起來的量爲2,節點b堆放起來的量爲21+3*1=5,即頂點e對b的偏導數爲5.

舉個不太恰當的例子,如果把圖中的箭頭表示欠錢的關係,即c→e表示e欠c的錢。以a, b爲例,直接計算e對它們倆的偏導相當於a, b各自去討薪。a向c討薪,c說e欠我錢,你向他要。於是a又跨過c去找e。b先向c討薪,同樣又轉向e,b又向d討薪,再次轉向e。可以看到,追款之路,充滿艱辛,而且還有重複,即a, b都從c轉向e。而BP算法就是主動還款。e把所欠之錢還給c,d。c,d收到錢,樂呵地把錢轉發給了a,b,皆大歡喜。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章