1.平方差損失函數 && Sigmoid激活函數
1.1 Sigmoid函數
Sigmoid函數的表達式爲:σ(z)=1+e−z1 對應的函數圖像爲:
觀察圖像可發現,Sigmoid函數將輸入的實數值壓縮到(0,1)的實數範圍內。更進一步地說,Sigmoid函數將很大的負數變爲了0,將很大的正數變爲了1。
在以前,Sigmoid函數因爲具有良好的神經元激活頻率的解釋(從完全不激活0到完全激活狀態1),經常被用作神經網絡的激活函數,然而現在不太受歡迎了,主要是因爲以下三個缺點:
1.Sigmoid函數飽和時使梯度消失。Sigmoid神經元有一個不好的特性,就是當神經元的激活值在接近0或1處會飽和,在這些區域,會導致梯度幾乎爲0(從圖像可以看到,導數值幾乎爲0)!回顧一下,在反向傳播的時候,我們更新Wl和bl梯度時,都會乘上Sigmoid的梯度,如果這個Sigmoid的梯度非常小,那麼就會導致相乘的最終結果爲接近0,即導致梯度消失。(文章下面會有詳細公式說明)
2.Sigmoid函數的輸出不是零中心的,這沒有滿足我們想要的性質。在神經網絡後面層中的神經元,得到的輸入值(上一層的激活值)數據不是零中心的,如果輸入的數據總是正數,那麼關於w的梯度,在反向傳播的過程中,將會要麼全是正數,要麼全是負數,導致梯度更新時,權重出現Z字型抖動,導致收斂的速度會變得很慢。不過如果採用批量梯度下降法時,整個批量的數據的梯度加起來,權重的更新會有不同的正負,收斂速度加快,因此相比於上個問題而言,這只是一個小問題。
3.Sigmoid函數中,涉及到指數運算,相比於其他的激活函數而言,這個計算起來較慢。
1.2 平方差損失函數在反向傳播時的Wl和bl梯度更新式
根據上一節所學,可知梯度的計算如下:
∂Wl∂J(W,b,a,y)∂bl∂J(W,b,a,y)=∂zl∂J(W,b,a,y)∂Wl∂zl=δl(al−1)T=∂zl∂J(W,b,a,y)∂bL∂zl=δl 其中,δl爲:
δl=δl+1∂zl∂zl+1=(Wl+1)Tδl+1⊙σ′(zl) 因爲是反向傳播,所以在計算δl時,Wl+1和δl+1都是已知的。
然後再按照梯度下降,更新Wl和bl值如下:
Wl=Wl−α∂Wl∂J(W,b,a,y)bl=bl−α∂bl∂J(W,b,a,y)
這裏從公式的角度,印證了上面的觀點,平方差損失函數&&Sigmoid激活函數的組合,在進行梯度更新時,梯度式子裏包含了σ′(z)項,很容易因爲激活函數的梯度趨近於0而導致整體梯度式子的值爲0,即發生梯度消失!
2.交叉熵損失函數 && Sigmoid激活函數
2.1 交叉熵損失函數
在之前的學習中,我們有了解到,交叉熵損失函數實際上是從KL散度推導出來的,用來比較兩個變量分佈的差異程度,交叉熵越小,表示兩個分佈差異越小,先來看看二分類任務中,交叉熵損失函數的定義:
H(y,y^)=−[ylny^+(1−y)ln(1−y^)] 這裏我們爲了同上面平方差損失函數的表示一致,定義二分類任務中,每個樣本的交叉熵損失函數爲:
J(W,b,a,y)=−[ylna+(1−y)ln(1−a)] 使用了交叉熵損失函數時,先來看看輸出層δL的梯度情況:δL=∂zL∂J(W,b,aL,y)=−yaL1(aL)(1−aL)+(1−y)1−aL1(aL)(1−aL)=−y(1−aL)+(1−y)aL=aL−y 上式中應用了Sigmoid函數求導的性質,即:(aL)′=(aL)(1−aL) 言歸正傳,我們驚喜的發現,使用交叉熵損失函數之後,我們的梯度式δL中不再包含σ′(z)項了,梯度只和預測值aL與真實值 y的差值有關,既滿足了我們訓練神經網絡的要求,“在訓練過程中,真實值與預測值的誤差越大,那麼梯度下降的幅度就越大”,又加快了收斂的速度(少了σ′(z)的干擾),因此,在用Sigmoid函數作爲激活函數的時候,交叉熵損失函數比平方差損失函數的效果更加出色!
不過在隱藏層中,依舊會存在大量的累乘操作,還是會存在很多個σ′(z)項,因此交叉熵損失函數沒辦法解決梯度消失問題,只是說相對而言,可以加快參數W,b 的收斂速度。
3.梯度消失與梯度爆炸
簡單來說,梯度消失和梯度爆炸,實際上屬於一種情況,在反向傳播的過程中,由於我們使用了矩陣求導的鏈式法則,有一大串的連乘操作,如果連乘的數字都是小於1的,則梯度越往前乘就越小,最終趨近於0,梯度更新的信息量以指數形式衰減,即“梯度消失”;如果連乘的數字都是大於1的,則梯度越往前乘就越大,梯度更新的信息量以指數形式增大,即“梯度爆炸”。
3.1 梯度消失
梯度消失往往在兩種情況下常發生,一是比較深的神經網絡,二是採用了不合適的損失函數與激活函數,如上面提到的平方差損失&&Sigmoid激活函數。
如下圖所示,一個簡單的深度神經網絡,一共有5層,每層只有一個神經元。
定義損失函數用C表示,那麼w1的梯度爲:
∂w1∂C=∂a5∂C∂z5∂a5∂a4∂z5∂z4∂a4∂a3∂z4∂z3∂a3∂a2∂z3∂z2∂a2∂w1∂z2
=∂a5∂Cσ′(z5)w4σ′(z4)w3σ′(z3)w2σ′(z2)x1
而Sigmoid的導函數σ′(z)圖像如下圖所示:
觀察發現,導函數最大值爲0.25,是一個小於1的值,如果我們初始化的w值很小的話,最終得到的梯度結果,就是一個接近於0的值,導致梯度消失。進而導致Wl和bl的值不會發生明顯的改變,也就更加談不上收斂了,對於網絡層數較深的神經網絡,遇到梯度消失的問題,暫時沒有比較好的解決辦法,不過設置ReLU函數作爲激活函數頗具成效,函數式爲σ(z)=max(0,z),它對應的導函數爲0或1。
3.2 梯度爆炸
梯度爆炸的產生原因和上面類似,主要是因爲連乘項中,初始化的權重值過大,導致每一層的wiσ′(zi)的值大於1,最終連乘起來得到一個很大的梯度值。其實對比於梯度消失的話,在激活函數是Sigmoid函數時,梯度爆炸反倒不太容易發生。
下面聊一聊如何解決梯度爆炸的情況。
1.設置梯度剪切閾值,如果超過了該閾值,直接將梯度置爲該值;
2.降低梯度更新式中的學習率
3.權重正則化
3.3 拓展
在深度神經網絡中,梯度消失、梯度爆炸產生的根本原因在於反向傳播訓練法則,屬於先天不足,Hinton提出capsule的原因就是爲了徹底拋棄反向傳播,如果真能大範圍普及,那真的是一個革命。
4.常用的神經網絡激活函數
4.1 tanh激活函數
tanh函數是Sigmoid函數的變種,表達式爲:tanh(z)=ez+e−zez−e−z tanh激活函數與Sigmoid激活函數的關係式爲:(tanh函數實質上就是一個放大了並往下平移1位的Sigmoid函數)tanh(z)=2sigmoid(2z)−1 tanh函數圖像如下:
觀察圖像可發現,Sigmoid函數將輸入的實數值壓縮到(-1,1)的實數範圍內。和Sigmoid函數一樣,它也存在飽和問題(輸入值往兩邊擴展時,對應的梯度值趨於0),導致梯度消失。
不過它的優點在於輸出是零中心的,因此在實際操作中,tanh激活函數與Sigmoid激活函數更受歡迎。
4.2 ReLU激活函數
ReLU函數,全稱是Rectified Linear Unit(修正線性單元),表達式爲: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=1mwjilail−1+bjl的值始終爲負數。爲什麼會這樣子呢?下面舉個例子說明:
假設神經網絡中傳入了一個異常輸入x,它的某一維特徵xi與wi相乘之後,得到的值是一個很大的正數,於是經過ReLU函數激活之後,輸出的值爲也是一個很大的正數,最終神經網絡的輸出aL與y的差異也很大,根據前面的學習我們知道,在反向傳播時,將會產生一個很大的梯度值,根據bias項的梯度更新式,b:=b−η∂b∂C,如果剛好學習率也設置的很大的話,那麼b最終會變成一個值很小的負數,在之後進行常規輸入時,zjl的值將會因爲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<0)(αx)+1(x>=0)(x) 其中α是一個比較小的常量如0.01。有些研究者的論文指出這個激活函數表現很不錯,但是其效果並不是很穩定。Kaiming He等人在2015年發佈的論文Delving Deep into Rectifiers中介紹了一種新方法PReLU,把負區間上的斜率當做每個神經元中的一個參數。然而該激活函數在不同任務中均有益處的一致性並沒有特別清晰。
Leaky ReLU 函數圖像如下:
4.4 Maxout激活函數
Maxout(由Goodfellow等發佈)對於權重和輸入值的內積結果不再使用函數形式,而是 max(W1TX+b1,W2TX+b2) 的形式,即有兩組(或多組)不同的W矩陣和bias向量,Maxout是對ReLU和Leaky ReLU的一般化歸納,當W2,b2=0 的時候,它就退化成ReLU神經元。這樣Maxout神經元就擁有了ReLU的全部優點(非線性和不飽和),而沒有它的缺點(死亡神經元),不過最大的缺點就是訓練的參數變得更大,倍數增加。
4.5 小結
到底用哪種神經元呢?推薦用ReLU激活函數,設置好學習率,或者監控神經網絡中死亡神經元的佔比,如果佔比過高,可以嘗試Leaky ReLU或者Maxout。實在不行,也可以試試tanh激活函數,儘量避免用Sigmoid激活函數(容易導致梯度消失,無法收斂)。
參考資料
1.劉建平Pinard《深度神經網絡(DNN)損失函數和激活函數的選擇》
2.CS231n課程講義翻譯:神經網絡1
3.詳解機器學習中的梯度消失、爆炸原因及其解決方法
4.談談由異常輸入導致的 ReLU 神經元死亡的問題