㈠ 解讀反向傳播演算法(BackPropagation)
冒泡~周末愉快鴨!
舉個例子:
如下圖所示,這是 帶有一個隱層的三層神經網路 ,
-小女孩→隱藏層節點
-小黃帽→輸出層節點
-哆啦A夢→誤差
小女孩左側接受輸入信號,經過隱層節點產生輸出結果,哆啦A夢則指導參數往更優的方向調整。 由於哆啦A夢可以直接將誤差反饋給小黃帽,所以與小黃帽直接相連的左側參數矩陣可以直接通過誤差進行參數優化(實縱線);而與小女孩直接相連的左側參數矩陣由於不能得到哆啦A夢的直接反饋而不能直接被優化(虛棕線)。但由於反向傳播演算法使得哆啦A夢的反饋可以被傳遞到小女孩那進而產生間接誤差,所以與小女孩直接相連的左側權重矩陣可以通過間接誤差得到權重更新,迭代幾輪,誤差會降低到最小。( 也就是說小男孩得到的是直接誤差,小女孩是間接誤差 )
接下來將用例子演示整個過程
假設有下圖這樣一個帶權值的網路層,第一層是輸入層,包含兩個神經元i1,i2,和截距項b1;第二層是隱含層,包含兩個神經元h1,h2和截距項b2,第三層是輸出o1,o2,每條線上標的wi是層與層之間連接的權重,激活函數我們默認為sigmoid函數。
通過前向傳播我們得到輸出值為[0.75136079 , 0.772928465],與實際值[0.01 , 0.99]相差還很遠,接下來我們對誤差進行反向傳播,更新權值,重新計算輸出。
3.輸入層---->隱含層的權值更新:
在上文計算總誤差對w5的偏導時,是從out(o1)---->net(o1)---->w5,但是在隱含層之間的權值更新時,是out(h1)---->net(h1)---->w1,而out(h1)會接受E(o1)和E(o2)兩個地方傳來的誤差,所以這個地方兩個都要計算。
根據BP演算法的過程演示,可以得到BP演算法的一般過程:
1. 正向傳播FP(求損失)
此過程中,我們根據輸入的樣本、給定的初始化權重值W和偏置項的值b, 計算最終輸出值以及輸出值與實際值之間的損失值。( 注意:如果損失值不在給定的范圍內則進行接下來反向傳播的過程, 否則停止W,b的更新。 )
2.反向傳播BP(回傳誤差)
將輸出以某種形式通過隱層向輸入層逐層反傳,並將誤差分攤給各層的所有單元,從而獲得各層單元的誤差信號,此誤差信號即作為修正各單元權值的依據。( 主要為: ①隱層到輸出層的參數W的更新 ②從輸入層到隱層的參數W的更新。 )
Ending~理解計算和公式還是很重要的鴨!
㈡ 循環神經網路(RNN)簡介
循環神經網路英文名稱為 ( Recurrent Neural Network, RNN ),其通過使用帶自反饋的神經元,能夠處理任意長度的 時序 數據。
給定輸入時序序列
式中, 表示一段時序數據, 為時間長度
以一段英文段落為例,其時序數據可以表示為:
若是一段視頻,將其每一幀通過CNN網路處理得到相應的編碼向量
循環神經網路通過以下公式更新隱藏層的活性值
循環神經網路圖示
RNN的基本模型如下圖所示,為便於理解,圖中將RNN的模型展開,按照時序方向對其前向傳播流程進行介紹
RNN的基本模型
利用數學表達式整個過程可以變得更加清晰,RNN的前向傳播公式如下:
將上述過程整合到一個RNN cell中,可以表示為如下圖所示的過程:
RNN的前向傳播示意圖
缺陷:
沒有利用到模型後續的信息,可以通過雙向RNN網路進行優化
RNN主要有兩種計算梯度的方式:隨時間反向傳播(BPTT)和實時循環學習法(RTRL)演算法
本文中主要介紹隨時間反向傳播的方法 ( BackPropagation Through Time )
RNN的損失函數與任務有關,對於同步的序列對序列任務,其loss可以用交叉熵公式表示
然後通過BPTT演算法便可以進行梯度的反向傳播計算
梯度爆炸的解決方法:梯度修剪
梯度消失的解決方法:增加長程依賴 LSTM,GRU
GRU的基本思路:增加相關門(Relate Gate)和更新門(Update Gate),進而使得RNN單元具有記憶能力
首先從數學角度對GRU的前向傳播過程進行介紹,具體公式如下:
公式中各變數的含義:
將上述數學公式轉化為圖像,可得
GRU Cell的前向傳播流程
LSTM意為長短時記憶網路 (Long Short-Term Memory Network,LSTM) ,可以有效地解決簡單神經網路的梯度消失和爆炸問題
在LSTM中,與GRU主要有兩點不同
同樣,先從數學公式入手,對LSTM的前向傳播過程進行了解
基於數學公式的過程,可將LSTM CELL的前向傳播過程總結為(圖片借用於nndl):
LSTM Cell的前向傳播示意圖
從上圖中可以看出,LSTM在前向傳播的過程中傳輸了兩個狀態:內部狀態 以及外部狀態 ,在整個傳播過程中 外部狀態(隱狀態) 每個時刻都會被重寫,因此可以看作一種 短時記憶 ,而 內部狀態 可以在某個時刻捕捉一些關鍵信息,並將此信息保存一段時間間隔,可以看作一種 長時記憶 (長的短時記憶)
此外,在LSTM網路初始化訓練的時候,需要手動將遺忘門的數值設置的大一些,否則在參數初始化的時候,遺忘門的數據會被初始化為一個很小的值,前一時刻的內部狀態 大部分都會丟失,這樣網路很難獲取到長距離的依賴信息,並且相鄰時間間隔的梯度會非常小,導致 梯度彌散 問題,因此遺忘門的 偏置變數 的初始值 一般很大,取 1或2
將 設置為1即可,但是長度非常的大的時候會造成記憶單元的飽和,降低性能
三個門不僅依賴於 和 ,也依賴於
將兩者合並為一個門,即:
首先,我們要理解什麼是深層的RNN,對於單個的RNN cell,若將其在時間維度上展開,其深度與時間維度的長度成正比,但若將一個RNN cell看作為單個從 的映射函數,則單個cell實際上是很淺顯的一層,因此深層循環神經網路要做的就是把多個RNN cell組合起來,換句話說,就是增加從輸入 到輸出 的路徑,使得網路的深度更深。
如何增加從輸入 到輸出 的路徑呢?兩種途徑:
堆疊循環神經網路示意圖
將網路帶入到實際應用場景中:假如我們要翻譯一段句子
在這里,is和are實際上是由後面的Lucy和they所決定的,而這種單向的按照時序進行傳播的方式沒有利用到後面的信息。因此誕生了雙向循環網路
雙向循環神經網路示意圖
雙向循環神經網路實際上就是簡單的雙層循環神經網路,只不過第二層網路的傳播方式為按時序的逆向傳播,其傳播公式為:
㈢ 讀懂反向傳播演算法(bp演算法)
反向傳播演算法可以說是神經網路最基礎也是最重要的知識點。基本上所以的優化演算法都是在反向傳播算出梯度之後進行改進的。同時,也因為反向傳播演算法是一個遞歸的形式,一層一層的向後傳播誤差即可,很容易實現(這部分聽不懂沒關系,下面介紹)。不要被反向傳播嚇到,掌握其核心思想就很容易自己手推出來。
我們知道神經網路都是有一個loss函數的。這個函數根據不同的任務有不同的定義方式,但是這個loss函數的目的就是計算出當前神經網路建模出來輸出的數據和理想數據之間的距離。計算出loss之後,根據反向傳播演算法就可以更新網路中的各種參數以此使loss不斷下降,即可使輸出的數據更加理想。
所以,現在的任務是,已知一個網路的loss之後,如何根據loss來更新參數呢?具體點即如何更新網路節點中的權重w和偏差b的值呢?
這里我們採用的是全連接神經網路進行說明。
要想把這個過程說清楚,首先需要將神經網路中各個參數用文字表達清楚。定義的就是w和b在網路中的准確位置。
對於 表示的是神經網路中第 層第k個節點到神經網路中第 層第j個節點之間的權重。注意w的下標是首位表示的是節點後層節點的位置,末尾表示是前層節點的位置。理解這樣的表達方式在後面的計算中會很好理解。
同理,對於b的表示:
b的表示相比於w要簡單一些,符號 表示第l層網路在第j個節點的偏置。無論w還是b的表示,上標都是表示層數。並且 和 表示都是第l層網路第j個節點的參數。所以該節點的輸出可以表示為:
神經網路輸出之後會經過一個激活函數,這用激活函數用 表示,則經過激活函數輸出為:
至此,根據上面符號 、 、 、 。我們可以對於神經網路裡面每一個數據准確的表示了。
給定一個損失函數之後,用 表示,說白了反向傳播就是求∂C/∂w和∂C/∂b,然後將這個值乘以和對應的w,b進行相減就可以實現一次的參數更新了。為什麼這樣的操作就可以優化網路,減小loss值呢?
來源於導數的概念和速度相關。∂C/∂w和∂C/∂b相當於loss值C相對於w和v變化的速度。如果∂C/∂w是正的,則增大w,C也會增大,如果希望C減小的話,應該減小w;並且∂C/∂w的絕對值越大,表示w對C的值影響越大,w稍微有一點變化,C就會有大幅變化。如果要優化C變小,w應該對應的減少多少呢?也沒有一個確定的答案。這里通過變化的速度和學習率相乘作為一個減小的值。通過多輪迭代。最終是希望c達到最小點。而當函數落入最小值的時候,無論是局部最小還是全局最小,其周圍一定是平滑的。所以此時∂C/∂w和∂C/∂b將會變得很小甚至為0,即參數不在更新了。當函數在局部最小點處參數不在更新出現梯度消失的問題時,目前也有各種trick進行解決。不是這里的重點。
為了好說明,這里定義一個很簡單的損失函數C:
接下來就是有意思的階段了。這里還是利用上一節中∂C/∂w和∂C/∂b的解釋。如果我們想要求出∂C/∂w和∂C/∂b的值,即具體的 、 對C影響速率的值,我們找一個中間變數∂C/∂ 。因為我們知道:
我們定義:
當我們知道了 值之後,我們根據 式子可以很容易求出 。
利用導數的鏈式法則:
很容易推出來不是?同理可以求出:
可以看出通過媒介 很容易求出∂C/∂w和∂C/∂b。那麼我們現在來理解一下 到底是什麼意思,以及如何求出來每一個l層j節點的 值。
根據定義:
可以看出來 就是 對於C的影響大小(聯系之前說的導數和速率的關系)。而 是第 層第 個神經元未進過激活函數之前的輸出。所以我們可以理解 為網路中第 層第 個神經元對loss的影響。所以很直觀的看法就是我們先求出單個神經元對loss值得影響,然後再計算該神經元內部參數對於loss的影響。
ok,如果我們已經理解了為什麼要引入 變數以及如何利用該變數計算具體參數的梯度後,接下來我們就可以看看如何獲得 值。反向傳播的名字我想也就是通過計算 的方式而來的。是一層一層遞歸而來的。
既然說是遞歸的方式,我們來思考一下 和 之間有什麼關系,如果找到這個關系之後,我們就可以默認我們如果知道最後一層網路節點的 值,我們就可以獲得倒數第二層網路節點的 值,倒數第三層,倒數第四層,……以此推類即可獲得整個網路的每個節點的 值。至此我們的反向傳播也基本完成了。
所以最重要的有兩點:
先看問題1,直接根據求導的鏈式法則就可以找出兩個的關系,具體公式如下,可以多看看手寫一下,思路上也很簡單。
覺得這樣的鏈式公式還是很直觀的,如果不好理解,可以自己畫一個神經網路圖,連上節點與節點之間的線,標上參數,然後推一下應該就能理解了。
這里的 都表示的未經過激活函數的神經元的輸出。 表示激活函數。因為:
所以:
帶入上式就可以得出:
至此就找出了 和 之間的關系了。
(還能簡化,根據最開始我們定義的 )。
理解起來就是網路中前面一層某一個神經元對於loss的影響與該層的後一層所有的神經元對loss的影響、該神經元的輸出大小、該神經元與後一層神經元連接的權重有關系的,並且是一個累加的效應。這樣的理解也是非常直觀合乎常理的。
現在萬事具備,只差問題2了。即假設最後一層網路是L,最後一層 如何計算得出。最後一層的 值就像一個導火索,一旦有了開始,就可以利用我們之前推出來的: 公式進行反向傳播了(反向傳播還是很形象的不是?)。現在解決這個問題。這個問題就是和損失函數具體怎麼定義有關系了。不過我們先不考慮C的具體形式,根據通用的鏈式法則我們可以得到:
這里需要注意的是最後一層激活函數使用的是哪種。最後一層激活函數在計算某一個神經元的輸出時可能會結合其他節點的輸出來計算。比如softmax激活函數,其輸出的是一個概率值【0,1】。輸出大小就是結合輸出所有的值。
現在我們來考慮兩個具體的損失函數,並且採用之前定義的均方誤差損失函數 :
求導為:
因為sigmoid輸出的值僅僅和輸入的x值有關 。所以 當 時值為0.所以:
根據上面,BP推導有三部曲,先求出 ,再根據 分別求出 、 。總結公式如下:
啟動上面反傳的導火索是最後一層的 值,計算公式為:
根據最後一層不同類型的激活函數不同對待。