十分鍾看懂神經網絡反向傳輸算法


昨天面試被問到如何推導BP(反向傳輸)算法,頓時蒙住了,大體是知道反向傳輸算法的過程的,但是用語言描述出來,確實有些困難。回來后看了些博文,發現有的博文中公式推導過於復雜,不易理解,遂綜合了網絡中其他博文和斯坦福大學CS231n課程中的內容,整理了一份反向傳輸算法的通俗解釋,如有錯誤,請各位網友指出。

一、反向傳輸(BP)算法的作用是什么?

首先我們要知道我們的優化目標是什么,對於神經網絡模型的優化實質上就是對整體損失函數 L(成本函數) 的優化

其中 L為樣本集中第 i 個樣本的損失值,(xi,yi)為第i個樣本。

損失函數 L 的自變量是網絡中所有的參數,訓練的目的是找到一組參數,使得損失函數 L 達到最小值(或者局部最小值)。通常使用梯度下降算法進行優化參數,對於具體的優化算法,這里不再敘述,具體可以參看深度學習——優化器算法Optimizer詳解BGDSGDMBGDMomentumNAGAdagradAdadeltaRMSpropAdam一文。這些算法都是闡述了如何更好的使用梯度信息來快速優化成本函數、找到最有解,但這些算法的前提都是獲得了成本函數的梯度值,對於深度網絡可能有上億的參數需要優化,如何高效的求解出 L 對這上億參數的偏導數,便成為一個難題,反向傳輸(BP)算法即用來高效的計算這些參數的偏導數,進而得出成本函數(損失函數L)的梯度。

補充:

對於欲優化的代價函數,為權重的函數C=C(W),是一個非常復雜的復合函數,直接使用鏈式法則對各參數求偏導非常復雜。如果使用導數定義進行樹數值求導,一個很明顯的計算方式是使用近似:

其中是一個大於零的小正數。換句話說,我們可以通過計算兩個差距很小的wj的代價,然后利用上式來估計。這個方法看起來很不錯,使用的是導數的定義求法,但是計算過於復雜,設想我們的神經網絡中有100萬個待優化的參數,計算一次梯度就要重復計算100萬次。進而對於每一個樣本,都要在神經網絡中向前傳播100萬次。而且還需要計算C(W),相當於要一百萬零一次前向傳播。

反向傳播的優點在於他盡力用一次前向傳播加一次反向傳播就可以同時計算出所有的偏導數,大致來講,反向傳播所需要的總計算量與前向傳播的計算量基本相等,原因在於前向傳播時主要的計算量在於權重矩陣的乘法計算,反向傳播時主要的計算量在於權重矩陣轉置的乘法,很明顯,它們的計算量差不多。利用反向傳播算法求成本函數的梯度,大大減小了計算量,使神經網絡優化更快!

舉個例子:

二、反向傳輸算法過程

1.鏈式求導

首先我們回顧一下微積分中對於復合函數的求導過程,對於任意復合函數,例如:

這就是我們常說的鏈式求導法則。反向傳輸算法正是利用了這種鏈式求導法則。

2.用計算圖來解釋幾種求導方法

2.1 計算圖

式子 e=(a+b)*(b+1) 可以用如下計算圖表達:

 

令a=2,b=1則有:

如何在計算圖上表達“求導”呢? 導數的含義是因變量隨自變量的變化率,例如 \frac{\partial y }{\partial x} = 3  表示當x變化1個單位,y會變化3個單位。 微積分中已經學過:加法求導法則是 \frac{\partial}{\partial a}(a+b) = \frac{\partial a}{\partial a} + \frac{\partial b}{\partial a} = 1 乘法求導法則是 \frac{\partial}{\partial u}uv = u\frac{\partial v}{\partial u} + v\frac{\partial u}{\partial u} = v 。 我們在計算圖的邊上表示導數或偏導數:\frac{ \partial e }{ \partial c } , \frac{ \partial e }{ \partial d }, \frac{ \partial c }{ \partial a }, \frac{ \partial c }{ \partial b }, \frac{ \partial d }{ \partial b } 如下圖

那么 \frac{ \partial e  }{ \partial b } 如何求呢? \frac{\partial c }{ \partial b} = 1 告訴我們1個單位的b變化會引起1個單位的c變換,\frac{\partial e }{ \partial c} = 2告訴我們 1 個單位的c變化會引起2個單位的e變化。所以 \frac{ \partial e  }{ \partial b } =   \frac{ \partial c }{ \partial b } * \frac{ \partial e  }{ \partial c }   = 1*2 =2 嗎? 答案必然是錯誤。因為這樣做只考慮到了下圖橙色的路徑,所有的路徑都要考慮:\frac{ \partial e  }{ \partial b } =   \frac{ \partial c }{ \partial b } * \frac{ \partial e  }{ \partial c }  +  \frac{ \partial d  }{ \partial b }  *  \frac{ \partial e  }{ \partial d }  =1*2 + 1 * 3 = 5

所以上面的求導方法總結為一句話就是: 路徑上所有邊相乘,所有路徑相加。不過這里需要補充一條很有用的合並策略:

例如:下面的計算圖若要計算\frac{\partial Z}{\partial X}就會有9條路徑:\frac{\partial Z}{\partial X} = \alpha\delta + \alpha\epsilon + \alpha\zeta + \beta\delta + \beta\epsilon + \beta\zeta + \gamma\delta + \gamma\epsilon + \gamma\zeta

如果計算圖再復雜一些,層數再多一些,路徑數量就會呈指數爆炸性增長。但是如果采用合並策略:\frac{\partial Z}{\partial X} = (\alpha + \beta + \gamma)(\delta + \epsilon + \zeta) 就不會出現這種問題。這種策略不是 對每一條路徑都求和,而是 “合並同類路徑”,“分階段求解”。先求X對Y的總影響 (\alpha + \beta + \gamma) 再求Y對Z的總影響 (\delta + \epsilon + \zeta) 最后綜合在一起。

2.2 兩種求導模式:前向模式求導( forward-mode differentiation) 反向模式求導(reverse-mode differentiation)

上面提到的求導方法都是前向模式求導( forward-mode differentiation) :從前向后。先求X對Y的總影響 (\alpha + \beta + \gamma) 再乘以Y對Z的總影響 (\delta + \epsilon + \zeta) 。

另一種,反向模式求導(reverse-mode differentiation) 則是從后向前。先求Y對Z的影響再乘以X對Y的影響。

前向求導模式追蹤一個輸入如何影響每一個節點(對每一個節點進行 \frac{\partial}{\partial X}操作)反向求導模式追蹤每一個節點如何影響一個輸出(對每一個節點進行 \frac{\partial Z}{\partial}操作)。通俗點理解,前向求導模式和反向求導模式只是求導順序的不同,但是順序不同運算復雜度也不相同。

2.3 反向求導模式(反向傳播算法)的重要性

讓我們再次考慮前面的例子:

如果用前向求導模式:關於b向前求導一次

 

 

如果用反向求導模式:向后求導

前向求導模式只得到了關於輸入b的偏導 \frac{\partial e}{\partial b} ,還需要再次求解關於輸入a的偏導\frac{\partial e}{\partial a} (運算2遍)。而反向求導一次運算就得到了e對兩個輸入a,b的偏導\frac{\partial e}{\partial a}, \frac{\partial e}{\partial b} (運算1遍)。上面的比較只看到了2倍的加速。但如果有1億個輸入1個輸出,意味着前向求導需要操作1億遍才得到所有關於輸入的偏導,而反向求導則只需一次運算,1億倍的加速。

當我們訓練神經網絡時,把“損失“ 看作 ”權重參數“ 的函數,需要計算”損失“關於每一個”權重參數“的偏導數(然后用梯度下降法學習)。 神經網絡的權重參數可以是百萬甚至過億級別。因此反向求導模式(反向傳播算法)可以極大的加速學習。

用更通俗易懂的話來描述反向傳輸算法,從目標函數開始,逐層向前求解每一層每個結點(運算)的局部梯度,根據鏈式法則可知,整個網絡中成本函數對於某一個參數的偏導數,從成本函數流經本參數所有指路上的偏導數乘積疊加,這樣一次運算就可以獲得所有參數的偏導數,即成本函數的梯度。梯度從后向前逐層傳遞。

通過計算流圖對該算法進行簡要解釋:


 

 附錄:機器學習常用求導公式

 X是向量,W是與X無關的矩陣

后兩個很重要!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM