【2】深度神經網絡的損失函數/激活函數

1.平方差損失函數 && Sigmoid激活函數

1.1 Sigmoid函數

       Sigmoid函數的表達式爲:σ(z)=11+ez \sigma(z)=\frac{1}{1+e^{-z}}        對應的函數圖像爲:

       觀察圖像可發現,Sigmoid函數將輸入的實數值壓縮到(0,1)的實數範圍內。更進一步地說,Sigmoid函數將很大的負數變爲了0,將很大的正數變爲了1。

       在以前,Sigmoid函數因爲具有良好的神經元激活頻率的解釋(從完全不激活0到完全激活狀態1),經常被用作神經網絡的激活函數,然而現在不太受歡迎了,主要是因爲以下三個缺點:

1.Sigmoid函數飽和時使梯度消失。Sigmoid神經元有一個不好的特性,就是當神經元的激活值在接近0或1處會飽和,在這些區域,會導致梯度幾乎爲0(從圖像可以看到,導數值幾乎爲0)!回顧一下,在反向傳播的時候,我們更新WlblW^l和b^l梯度時,都會乘上Sigmoid的梯度,如果這個Sigmoid的梯度非常小,那麼就會導致相乘的最終結果爲接近0,即導致梯度消失。(文章下面會有詳細公式說明)

2.Sigmoid函數的輸出不是零中心的,這沒有滿足我們想要的性質。在神經網絡後面層中的神經元,得到的輸入值(上一層的激活值)數據不是零中心的,如果輸入的數據總是正數,那麼關於w的梯度,在反向傳播的過程中,將會要麼全是正數,要麼全是負數,導致梯度更新時,權重出現Z字型抖動,導致收斂的速度會變得很慢。不過如果採用批量梯度下降法時,整個批量的數據的梯度加起來,權重的更新會有不同的正負,收斂速度加快,因此相比於上個問題而言,這只是一個小問題。

3.Sigmoid函數中,涉及到指數運算,相比於其他的激活函數而言,這個計算起來較慢。

1.2 平方差損失函數在反向傳播時的WlblW^l和b^l梯度更新式

       根據上一節所學,可知梯度的計算如下:
J(W,b,a,y)Wl=J(W,b,a,y)zlzlWl=δl(al1)TJ(W,b,a,y)bl=J(W,b,a,y)zlzlbL=δl \begin{aligned} \frac{\partial J(W, b, a, y)}{\partial W^{l}} &=\frac{\partial J(W, b, a, y)}{\partial z^{l}} \frac{\partial z^{l}}{\partial W^{l}}=\delta^{l}\left(a^{l-1}\right)^{T} \\\\ \frac{\partial J(W, b, a, y)}{\partial b^{l}} &=\frac{\partial J(W, b, a, y)}{\partial z^{l}} \frac{\partial z^{l}}{\partial b^{L}}=\delta^{l} \end{aligned}        其中,δl\delta^l爲:
δl=δl+1zl+1zl=(Wl+1)Tδl+1σ(zl) \delta^{l}=\delta^{l+1} \frac{\partial z^{l+1}}{\partial z^{l}}=\left(W^{l+1}\right)^{T} \delta^{l+1} \odot \sigma^{\prime}\left(z^{l}\right)        因爲是反向傳播,所以在計算δl\delta^l時,Wl+1W^{l+1}δl+1\delta^{l+1}都是已知的。

       然後再按照梯度下降,更新WlblW^l和b^l值如下:
Wl=WlαJ(W,b,a,y)Wl W^{l}=W^{l}-\alpha \frac{\partial J(W, b, a, y)}{\partial W^{l}} bl=blαJ(W,b,a,y)bl b^{l}=b^{l}-\alpha \frac{\partial J(W, b, a, y)}{\partial b^{l}}
       這裏從公式的角度,印證了上面的觀點,平方差損失函數&&Sigmoid激活函數的組合,在進行梯度更新時,梯度式子裏包含了σ(z)\sigma^{\prime}(z)項,很容易因爲激活函數的梯度趨近於0而導致整體梯度式子的值爲0,即發生梯度消失!

2.交叉熵損失函數 && Sigmoid激活函數

2.1 交叉熵損失函數

       在之前的學習中,我們有了解到,交叉熵損失函數實際上是從KL散度推導出來的,用來比較兩個變量分佈的差異程度,交叉熵越小,表示兩個分佈差異越小,先來看看二分類任務中,交叉熵損失函數的定義:
H(y,y^)=[ylny^+(1y)ln(1y^)] H(y, \hat{y})=-[y \ln \hat{y}+(1-y) \ln (1-\hat{y})]        這裏我們爲了同上面平方差損失函數的表示一致,定義二分類任務中,每個樣本的交叉熵損失函數爲:
J(W,b,a,y)=[ylna+(1y)ln(1a)] J(W, b, a, y)=-[y \ln a+(1-y) \ln (1-a)]        使用了交叉熵損失函數時,先來看看輸出層δL\delta^L的梯度情況:δL=J(W,b,aL,y)zL=y1aL(aL)(1aL)+(1y)11aL(aL)(1aL)=y(1aL)+(1y)aL=aLy \begin{aligned} \delta^{L} &=\frac{\partial J\left(W, b, a^{L}, y\right)}{\partial z^{L}} \\\\ &=-y \frac{1}{a^{L}}\left(a^{L}\right)\left(1-a^{L}\right)+(1-y) \frac{1}{1-a^{L}}\left(a^{L}\right)\left(1-a^{L}\right) \\\\ &=-y\left(1-a^{L}\right)+(1-y) a^{L} \\\\ &=a^{L}-y \end{aligned}        上式中應用了Sigmoid函數求導的性質,即:(aL)=(aL)(1aL) \left(a^{L}\right)^\prime = \left(a^{L}\right)\left(1-a^{L}\right)       言歸正傳,我們驚喜的發現,使用交叉熵損失函數之後,我們的梯度式δL\delta^L中不再包含σ(z)\sigma^{\prime}(z)項了,梯度只和預測值aLa^L與真實值 yy的差值有關,既滿足了我們訓練神經網絡的要求,“在訓練過程中,真實值與預測值的誤差越大,那麼梯度下降的幅度就越大”,又加快了收斂的速度(少了σ(z)\sigma^{\prime}(z)的干擾),因此,在用Sigmoid函數作爲激活函數的時候,交叉熵損失函數比平方差損失函數的效果更加出色!

       不過在隱藏層中,依舊會存在大量的累乘操作,還是會存在很多個σ(z)\sigma^{\prime}(z)項,因此交叉熵損失函數沒辦法解決梯度消失問題,只是說相對而言,可以加快參數W,bW,b 的收斂速度。

3.梯度消失與梯度爆炸

       簡單來說,梯度消失和梯度爆炸,實際上屬於一種情況,在反向傳播的過程中,由於我們使用了矩陣求導的鏈式法則,有一大串的連乘操作,如果連乘的數字都是小於1的,則梯度越往前乘就越小,最終趨近於0,梯度更新的信息量以指數形式衰減,即“梯度消失”;如果連乘的數字都是大於1的,則梯度越往前乘就越大,梯度更新的信息量以指數形式增大,即“梯度爆炸”

3.1 梯度消失

       梯度消失往往在兩種情況下常發生,一是比較深的神經網絡,二是採用了不合適的損失函數與激活函數,如上面提到的平方差損失&&Sigmoid激活函數。
       如下圖所示,一個簡單的深度神經網絡,一共有5層,每層只有一個神經元。

       定義損失函數用C表示,那麼w1的梯度爲:

Cw1=Ca5a5z5z5a4a4z4z4a3a3z3z3a2a2z2z2w1\frac{\partial C}{\partial w_{1}}=\frac{\partial C}{\partial a_{5}} \frac{\partial a_{5}}{\partial z_{5}} \frac{\partial z_{5}}{\partial a_{4}} \frac{\partial a_{4}}{\partial z_{4}} \frac{\partial z_{4}}{\partial a_{3}} \frac{\partial a_{3}}{\partial z_{3}} \frac{\partial z_{3}}{\partial a_{2}} \frac{\partial a_{2}}{\partial z_{2}} \frac{\partial z_{2}}{\partial w_{1}}

                          =Ca5σ(z5)w4σ(z4)w3σ(z3)w2σ(z2)x1\;\;\;\;\;\;\;\;\;\;\;\;\;=\frac{\partial C}{\partial a_{5}} \sigma^{\prime}\left(z_{5}\right) w_{4} \sigma^{\prime}\left(z_{4}\right) w_{3} \sigma^{\prime}\left(z_{3}\right) w_{2} \sigma^{\prime}\left(z_{2}\right)x_1
       而Sigmoid的導函數σ(z)\sigma^\prime(z)圖像如下圖所示:

       觀察發現,導函數最大值爲0.25,是一個小於1的值,如果我們初始化的w值很小的話,最終得到的梯度結果,就是一個接近於0的值,導致梯度消失。進而導致WlblW^l和b^l的值不會發生明顯的改變,也就更加談不上收斂了,對於網絡層數較深的神經網絡,遇到梯度消失的問題,暫時沒有比較好的解決辦法,不過設置ReLU函數作爲激活函數頗具成效,函數式爲σ(z)=max(0,z)\sigma(z)=\max (0, z),它對應的導函數爲0或1。

3.2 梯度爆炸

       梯度爆炸的產生原因和上面類似,主要是因爲連乘項中,初始化的權重值過大,導致每一層的wiσ(zi)w_i\sigma^\prime(z_i)的值大於1,最終連乘起來得到一個很大的梯度值。其實對比於梯度消失的話,在激活函數是Sigmoid函數時,梯度爆炸反倒不太容易發生。

       下面聊一聊如何解決梯度爆炸的情況。

1.設置梯度剪切閾值,如果超過了該閾值,直接將梯度置爲該值;
2.降低梯度更新式中的學習率
3.權重正則化

3.3 拓展

       在深度神經網絡中,梯度消失、梯度爆炸產生的根本原因在於反向傳播訓練法則,屬於先天不足,Hinton提出capsule的原因就是爲了徹底拋棄反向傳播,如果真能大範圍普及,那真的是一個革命。

4.常用的神經網絡激活函數

4.1 tanh激活函數

       tanh函數是Sigmoid函數的變種,表達式爲:tanh(z)=ezezez+ez \tanh (z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}}        tanh激活函數與Sigmoid激活函數的關係式爲:(tanh函數實質上就是一個放大了並往下平移1位的Sigmoid函數)tanh(z)=2sigmoid(2z)1 \tanh (z)=2 \operatorname{sigmoid}(2 z)-1        tanh函數圖像如下:

       觀察圖像可發現,Sigmoid函數將輸入的實數值壓縮到(-1,1)的實數範圍內。和Sigmoid函數一樣,它也存在飽和問題(輸入值往兩邊擴展時,對應的梯度值趨於0),導致梯度消失。不過它的優點在於輸出是零中心的,因此在實際操作中,tanh激活函數與Sigmoid激活函數更受歡迎。

4.2 ReLU激活函數

       ReLU函數,全稱是Rectified Linear Unit(修正線性單元),表達式爲:f(x)=max(0,x) f(x)=\max (0, x)        函數圖像爲:

       對應的導函數圖像爲:


       我們可以很容易看出,ReLU函數的導數在正數部分是恆等於1的,因此在深層神經網絡中使用ReLU激活函數就不會因爲激活函數的梯度值,而導致出現梯度消失和爆炸的問題。

4.2.1 ReLU激活函數的優點:

       (1)相較於非線性的Sigmoid和tanh函數,ReLU對於隨機梯度下降的收斂有巨大的加速作用( Krizhevsky 等的論文指出有6倍之多)。據稱這是由它的非線性,非飽和的公式導致的;
       (2)Sigmoid和tanh神經元含有指數運算等耗費計算資源的操作,而ReLU可以簡單地通過對一個矩陣進行閾值計算得到,不涉及到指數運算;

4.2.2 ReLU激活函數的缺點:

       在訓練的時候,ReLU單元比較脆弱並且可能“死掉”。舉例來說,當一個很大的梯度流過ReLU的神經元的時候,可能會導致梯度更新到一種特別的狀態,在這種狀態下神經元將無法被其他任何數據點再次激活。如果這種情況發生,那麼從此所有流過這個神經元的梯度將都變成0。也就是說,這個ReLU單元在訓練中將不可逆轉的死亡,因爲這導致了數據多樣化的丟失。例如,如果學習率設置得太高,可能會發現網絡中40%的神經元都會死掉(在整個訓練集中這些神經元都不會被激活)。通過合理設置學習率,這種情況的發生概率會降低。

       【疑問】如何理解ReLU神經元的“死亡”?

       對於任何輸入,“死”的ReLU神經元總是輸出相同的值(零)。(解釋“死”的定義)
 
       出現這種情況,意味着ReLU神經元的輸入始終爲一個負數,即zjl=i=1mwjilail1+bjlz_{j}^{l}=\sum_{i=1}^{m} w_{ji}^{l} a_{i}^{l-1} + b_j^l的值始終爲負數。爲什麼會這樣子呢?下面舉個例子說明:
 
       假設神經網絡中傳入了一個異常輸入xx,它的某一維特徵xix_iwiw_i相乘之後,得到的值是一個很大的正數,於是經過ReLU函數激活之後,輸出的值爲也是一個很大的正數,最終神經網絡的輸出aLa^Lyy的差異也很大,根據前面的學習我們知道,在反向傳播時,將會產生一個很大的梯度值,根據bias項的梯度更新式,b:=bηCbb := b-\eta \frac{\partial C}{\partial b},如果剛好學習率也設置的很大的話,那麼b最終會變成一個值很小的負數,在之後進行常規輸入時,zjlz_{j}^{l}的值將會因爲b,而大概率變爲一個負數,對下一層輸出0。
 
       一旦ReLU神經元最終處於這種死亡狀態,它就不太可能恢復,因爲0處的函數梯度也是0,所以梯度下降不會改變其權重W和bias項。針對此問題,改進後的Leaky ReLU可以解決此問題並提供給“死亡神經元”提供復活的可能性。
 
       Sigmoid和tanh神經元可能會遇到類似的問題,因爲它們的值飽和了,但至少總有一個小的梯度(不至於爲0)允許它們經過很長時間再恢復。

4.3 Leaky ReLU激活函數

      在上面有提到過,Leaky ReLU是爲解決“ReLU死亡”問題的嘗試。ReLU中當x<0時,函數值爲0。而Leaky ReLU則是給出一個很小的負數梯度值,比如0.01。所以其函數公式爲f(x)=1(x&lt;0)(αx)+1(x&gt;=0)(x) f(x)=1(x&lt;0)(\alpha x)+1(x&gt;=0)(x)       其中α\alpha是一個比較小的常量如0.01。有些研究者的論文指出這個激活函數表現很不錯,但是其效果並不是很穩定。Kaiming He等人在2015年發佈的論文Delving Deep into Rectifiers中介紹了一種新方法PReLU,把負區間上的斜率當做每個神經元中的一個參數。然而該激活函數在不同任務中均有益處的一致性並沒有特別清晰。
      Leaky ReLU 函數圖像如下:

4.4 Maxout激活函數

      Maxout(由Goodfellow等發佈)對於權重和輸入值的內積結果不再使用函數形式,而是 max(W1TX+b1,W2TX+b2)\max \left(W_{1}^{T} X+b_{1}, W_{2}^{T} X+b_{2}\right) 的形式,即有兩組(或多組)不同的W矩陣和bias向量,Maxout是對ReLU和Leaky ReLU的一般化歸納,當W2b2=0W_2,b_2 = 0 的時候,它就退化成ReLU神經元。這樣Maxout神經元就擁有了ReLU的全部優點(非線性和不飽和),而沒有它的缺點(死亡神經元),不過最大的缺點就是訓練的參數變得更大,倍數增加。

4.5 小結

      到底用哪種神經元呢?推薦用ReLU激活函數,設置好學習率,或者監控神經網絡中死亡神經元的佔比,如果佔比過高,可以嘗試Leaky ReLU或者Maxout。實在不行,也可以試試tanhtanh激活函數,儘量避免用Sigmoid激活函數(容易導致梯度消失,無法收斂)。


參考資料

1.劉建平Pinard《深度神經網絡(DNN)損失函數和激活函數的選擇》
2.CS231n課程講義翻譯:神經網絡1
3.詳解機器學習中的梯度消失、爆炸原因及其解決方法
4.談談由異常輸入導致的 ReLU 神經元死亡的問題

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