這篇文章主要整理三部分內容,一是常見的三種神經網絡結構:前饋神經網絡、反饋神經網絡和圖網絡;二是整理前饋神經網絡中正向傳播、誤差反向傳播和梯度下降的原理;三是梯度消失和梯度爆炸問題的原因及解決思路。
一、神經網絡結構
目前比較常用的神經網絡結構有如下三種:
1、前饋神經網絡
前饋神經網絡中,把每個神經元按接收信息的先后分為不同的組,每一組可以看做是一個神經層。每一層中的神經元接收前一層神經元的輸出,並輸出到下一層神經元。整個網絡中的信息是朝着一個方向傳播的,沒有反向的信息傳播(和誤差反向傳播不是一回事),可以用一個有向無環圖來表示。
前饋神經網絡包括全連接前饋神經網絡和卷積神經網絡。
前饋神經網絡可以看做是一個函數,通過簡單非線性函數的多次復合,實現輸入空間到輸出空間的復雜映射。
2、反饋神經網絡
反饋神經網絡中神經元不但可以接收其他神經元的信號,而且可以接收自己的反饋信號。和前饋神經網絡相比,反饋神經網絡中的神經元具有記憶功能,在不同時刻具有不同的狀態。反饋神經網絡中的信息傳播可以是單向也可以是雙向傳播,因此可以用一個有向循環圖或者無向圖來表示。
常見的反饋神經網絡包括循環神經網絡、Hopfield網絡和玻爾茲曼機。
而為了進一步增強記憶網絡的記憶容量,可以映入外部記憶單元和讀寫機制,用來保存一些網絡的中間狀態,稱為記憶增強網絡,比如神經圖靈機。
3、圖網絡
前饋神經網絡和反饋神經網絡的輸入都可表示為向量或者向量序列,但實際應用中很多數據都是圖結構的數據,比如知識圖譜、社交網絡和分子網絡等。這時就需要用到圖網絡來進行處理。
圖網絡是定義在圖結構數據上的神經網絡,圖中每個結點都由一個或者一組神經元組成。結點之前的連接可以是有向的,也可以是無向的。每個結點可以收到來自相鄰結點或自身的信息。
以下是這三種神經網絡結構的示意圖:
二、前饋神經網絡
在前饋神經網絡(Feedforward Neural Network, FNN )中,每一層的神經元可以接收前一層神經元的信號,並產生信號輸出到下一層。第0層叫做輸入層,最后一層叫做輸出層,其他中間層叫做隱藏層。整個網絡中無反饋,信號從輸入層向輸出層單向傳播,可用一個有向無環圖表示。
多層前饋神經網絡的圖示如下:
1、前饋神經網絡的前向傳播
用下面的記號來描述一個前饋神經網絡:
前饋神經網絡通過下面公式進行信息傳播:
這樣前饋神經網絡通過逐層的信息傳遞,得到網絡最后的輸出a(L)。整個網絡可以看做是一個復合函數,將向量x作為第1層的輸入a(0),將第L層的輸出a(L)作為整個函數的輸出。
2、前饋神經網絡的梯度下降法
神經網絡具有極其強大的擬合能力,可以作為一個萬能函數來使用,通過進行復雜的特征轉換,可以以任意精度來近似任何一個有界閉集函數。
類似於其他機器學習算法求解參數的數值計算方法,我們首先考慮用梯度下降法來進行參數學習。
如果采用交叉熵損失函數,對於樣本(x,y),其損失函數為:
其中y∈{0, 1}C是標簽y對應的one-hot向量表示,C是類別的個數。
給定訓練集D={(x(1), y(1)),(x(2), y(2)),...,(x(N), y(N))},將每個樣本x(n)輸入給前饋神經網絡,得到神經網絡的輸出后,其在訓練集D上的結構化風險函數為:
其中W和b分別表示網絡中所有的權重矩陣和偏置向量。是正則化項,公式為:
然后用梯度下降法來進行學習。在梯度下降法的每次迭代中,第l層的參數W(l)和b(l)的參數更新方式為:
梯度下降法需要計算損失函數對參數的偏導數,如果用鏈式法則對每個參數逐一求偏導,涉及到矩陣微分,效率比較低。所以在神經網絡中經常使用反向傳播算法來高效地計算梯度。
3、前饋神經網絡的誤差反向傳播算法
假設給定一個樣本(x,y),將其輸入到神經網絡模型中,得到損失函數為:,如果要采用梯度下降法對神經網絡的參數進行學習,那么就要計算損失函數關於每個參數的導數。
我們就拿第l層中的參數矩陣W(l)和b(l)為例,計算損失函數對參數矩陣的偏導數。但因為的計算涉及到矩陣微分,非常繁瑣,於是我們先計算W(l)中某個元素的偏導數
。根據鏈式法則有:
上面兩個公式中的第二項都是目標函數關於第l層的神經元z(l)的偏導數,稱為誤差項。那么我們需要計算三個偏導數:
,
和
。
(1)計算偏導數
由於z(l)和Wij(l)的函數關系為,所以偏導數為
其中Wi:(l)為權重矩陣W(l)的第i行。
(2)計算偏導數
因為z(l)與b(l)的函數關系為,因此偏導數是一個維度是m(l) × m(l) 的單位矩陣。
(3)計算誤差項
用δ(l)來定義第l層神經元的誤差項,它用來表示第l層神經元對最終損失的影響,也反映了最終損失對第l層神經元的敏感程度。
根據鏈式法則,第l層的誤差項為:
首先根據,其中fl(•)是按位計算的函數,計算的偏導數如下。diag(•)表示對角矩陣。
然后根據,有:
於是第l層的誤差項δ(l)最終表示為:
其中⊙表示向量的點積運算符,表示每個元素相乘。
上面這個公式就是誤差的反向傳播公式!因為第l層的誤差項可以通過第l+1層的誤差項計算得到。反向傳播算法的含義是:第l層的一個神經元的誤差項等於該神經元激活函數的梯度,再乘上所有與該神經元相連接的第l+1層的神經元的誤差項的權重和。
再回到開頭求兩個參數的公式:
里面的三個偏導數都已經求出來了。於是可以求出:
進一步,損失函數關於第l層權重W(l)梯度為:
而損失函數關於第l層偏置b(l)的梯度為:
於是在利用誤差反向傳播算法計算出每一層的誤差項后,就可以得到每一層參數的梯度。
基於誤差反向傳播算法(backpropagation,BP)的前饋神經網絡訓練過程可以分為以下三步:
1、在前向傳播時計算每一層的凈輸入z(l)和激活值a(l),直至最后一層;
2、用誤差反向傳播計算每一層的誤差項 δ(l);
3、計算每一層參數的偏導數,並更新參數。
使用隨機梯度下降的誤差反向傳播算法的具體訓練過程如下:
三、梯度消失和梯度爆炸
訓練神經網絡,尤其是深度神經網絡時,面臨的一個問題是梯度消失或者梯度爆炸,也就是神經元上的梯度會變得非常小或者非常大,從而加大訓練的難度。
1、原理
梯度消失(Vanishing Gradient Problem,或稱梯度彌散)的意思是,在誤差反向傳播的過程中,誤差經過每一層傳遞都會不斷衰減,當網絡層數很深時,神經元上的梯度也會不斷衰減,導致前面的隱含層神經元的學習速度慢於后面隱含層上的神經元。
在上面我們得到了神經網絡中誤差反向傳播的迭代公式:
誤差從輸出層反向傳播時,在每一層都要乘以該層的激活函數的導數,如果導數的值域小於1,甚至如Sigmoid函數在兩端的飽和區導數趨於0,那么梯度就會不斷衰減甚至消失。
與之相對的問題是梯度爆炸(Exploding Gradient Problem),也就是前面層中神經元的梯度變得非常大。與梯度消失不太一樣的是,梯度爆炸通常產生於過大的權重W。
總結一下就是:梯度消失通常出現在深層網絡和采用了不合適的損失函數(sigmoid)的情形,梯度爆炸一般出現在深層網絡和權值初始化值太大的情況下。
2、舉例
可以通過一個例子來更好的理解這兩個問題。來看一個簡單的深度神經網絡:每一層都只有一個神經元。如下圖是有三層隱含層的神經網絡:
這里w表示權重,b是偏置值,C是代價函數。然后通過計算代價函數關於第一個隱含神經元的偏置的梯度,以及關於第三個隱含神經元偏置的梯度
,來考察梯度消失和梯度爆炸問題。
經過推導可得梯度的公式:
(1)梯度消失
首先看公式中的導數σ'(z)。激活函數如果采用Sigmoid函數,則其導數為:,也就是說導數的最大值為0.25。
其次看公式中的權重w。如果用均值為0標准差為1的高斯分布來初始化網絡的權重,那么所有的權重會滿足|wj|<1。
那么就會與wjσ'(zj)<0.25,於是梯度公式中所有項相乘時,梯度以指數級下降;神經網絡的層數越深,梯度的值下降得更快。
然后再與第三個隱含神經元的梯度進行對比,如下圖。可見前面的神經元的偏置的梯度是后面的1/16甚至更小。所以梯度消失產生的原因主要就是激活函數的導數值太小。
(2)梯度爆炸
梯度爆炸的一個原因是網絡的權重設置得過大,比如在上圖中,讓wj=100 。然后選擇偏置使得σ'(zj)項不會太小,比如σ'(zj)=0.25,那么wjσ'(zj)=25。代入上面的梯度公式中,可以看到梯度以25的指數級增大,神經網絡的層數越深,梯度越大。這就帶來了梯度爆炸的問題。
3、解決
那么如何解決梯度消失和梯度爆炸的問題呢?
一般用以下幾種方法來解決梯度消失和梯度爆炸的問題。
(1)對於梯度消失問題,可以選擇導數比較大的激活函數,比如ReLU激活函數。
Sigmoid函數和Tanh函數都屬於兩端飽和型激活函數,使用這兩種激活函數的神經網絡,在訓練過程中梯度通常會消失,因此可以選擇其他激活函數來替代。
ReLU激活函數在正數部分的導數恆為1,每層網絡都可以得到相同的更新速度,因此在深層網絡中不會產生梯度消失和梯度爆炸的問題。
(2)對於梯度爆炸問題,可以采取梯度截斷和權重正則化的方法。
梯度截斷這個方案主要是針對梯度爆炸提出的,其思想是設置一個梯度截斷閾值,然后在更新梯度的時候,如果梯度超過這個閾值,那么就將其強制限制在這個范圍之內。
權重正則化就是在損失函數中,加入對網絡的權重進行懲罰的正則化項,比如權重的L1正則化或者L2正則化。如果發生梯度爆炸,權值的范數會變得非常大,通過正則化項進行懲罰,可以限制權重的值,從而減輕梯度爆炸的問題。
(3)選擇更好的隨機初始化權重的方法。
一是對每個權重都進行隨機初始化,盡量讓每個權重都不同,使不同神經元之間的區分性更好。
二是選擇合適的隨機初始化權重的區間,不能太小,也不能太大。一般而言,參數初始化的區間應該根據神經元的性質進行差異化的設置,如果一個神經元的輸入連接很多,那么每個輸入連接上的權重要小一些,以避免神經元的輸出過大(當激活函數為ReLU時,但輸出為正時導數都是1)或者過飽和(當激活函數為Sigmoid函數時,梯度會接近於0)
此外,還有Batchnorm(batch normalization)的方法,留待以后探究。
參考資料:
1、邱錫鵬:《神經網絡與深度學習》
2、Michael Nielsen:《Neural Network and Deep Learning》