激活函數:在多層神經網絡中,上層節點的輸出和下層節點的輸入之間具有一個函數關係,這個函數稱為激活函數(又稱激勵函數)
激活函數的本質:
激活函數是來向神經網絡中引入非線性因素的,通過激活函數,神經網絡就可以擬合各種曲線。
舉一個例子來說明:假如我的任務是,將下面的這幅圖中的三角形和圓形分開,也就是一個典型的二分類問題:
我們用肉眼能很輕鬆的得出結論:無法用一條直線將這兩種圖形完全分開。比如我這裡使用一個單層感知機:
方程:
就是上圖右邊的直線,無論如何更改參數,它都不能很好的完成這個二分類問題,因為問題本身就是
線性不可分
的。
在每一層疊加完後,我們為輸出與輸入之間加上一個激活函數,此時的方程就變成了這樣:
這樣也許就能將這個線性不可分的問題解決了。最後也許就是這個樣子:
常見的激活函數:
1. ReLU是目前使用最頻繁的一個函數(Rectified Linear Unit),如果你不知道你的激活函數應該選擇哪個,那麼建議你選擇ReLU試試。一般情況下,將ReLU作為你的第一選擇
公式:導數:
首先,Relu一定程度上緩解了梯度問題(正區間) 其次, 計算速度非常快,這一點也可以明顯比較出來。 最後, Relu加速了模型的收斂, 比sigmoid與tanh要快很多。
ReLu是分段線性函數,它的非線性性很弱,因此網絡一般要做得很深。但這正好迎合了我們的需求,因為在同樣效果的前提下,往往深度比寬度更重要,更深的模型泛化能力更好。所以自從有了Relu激活函數,各種很深的模型都被提出來了,一個標誌性的事件是應該是VGG模型和它在ImageNet上取得的成功.
ReLU也有幾個需要特別注意的問題:
1)ReLU的輸出不是zero-centered
2)某些神經元可能永遠不會被激活(Dead ReLU Problem),導致相應的參數永遠不能被更新。
有兩個主要原因可能導致這種情況產生:
1) 非常不幸的參數初始化,這種情況比較少見
2) learning rate太高導致在訓練過程中參數更新太大,不幸使網絡進入這種狀態。解決方法是可以採用Xavier初始化方法,以及避免將learning rate設置太大或使用adagrad等自動調節learning rate的算法。
人們為了解決Dead ReLU Problem,提出了將ReLU的前半段設為αx 非0,通常α=0.01 ( Leaky ReLU函數: f(x)=max(αx,x) )。為了解決zero-centered問題,提出了ELU (Exponential Linear Units) 函數,f(x)=x if x>0 otherwise a(e^x 1).
2. Sigmoid函數
公式:求導:
sigmod函數的導數:
雖然simoid函數有諸多缺陷,但依然是目前主流的激活函數之一。其主要有以下幾個缺陷:sigmoid 極容易導致梯度消失問題。
如果我們初始化神經網絡的權值為 [0,1] 之間的隨機值,由反向傳播算法的數學推導可知,梯度從後向前傳播時,每傳遞一層梯度值都會減小為原來的0.25倍,如果神經網絡隱層特別多,那麼梯度在穿過多層後將變得非常小接近於0,即出現梯度消失現象;當網絡權值初始化為 (1,+∞) (1,+∞)(1,+∞) 區間內的值,則會出現梯度爆炸情況。
計算費時。在神經網絡訓練中,常常要計算sigmid的值, 冪計算會導致耗時增加。但這不是什麼大問題,最多是換個顯卡, 模型跑的時間長點而已。 sigmoid 函數不是關於原點中心對稱的(zero-centered)。
3. Tanh函數:
公式:導數:
它解決了Sigmoid函數的不是zero-centered輸出問題,然而,梯度消失(gradient vanishing)的問題和冪運算的問題仍然存在。
4.Leaky ReLU函數(PReLU)
函數表達式
人們為了解決Dead ReLU Problem,提出了將ReLU的前半段設為αx 而非0,通常α=0.01。另外一種直觀的想法是基於參數的方法,即ParametricReLU:f(x)=max(αx,x) 其中α 可由方向傳播算法學出來。理論上來講,Leaky ReLU有ReLU的所有優點,外加不會有Dead ReLU問題,但是在實際操作當中,並沒有完全證明Leaky ReLU總是好於ReLU。
5.ELU (Exponential Linear Units) 函數
函數公式:
函數及其導數的圖像如下圖所示:
ELU也是為解決ReLU存在的問題而提出,顯然,ELU有ReLU的基本所有優點,以及:
不會有Dead ReLU問題輸出的均值接近0,zero-centered它的一個小問題在於計算量稍大。類似於Leaky ReLU,理論上雖然好於ReLU,但在實際使用中目前並沒有好的證據ELU總是優於ReLU。
6.MaxOut函數
這個函數可以參考論文《maxout networks》,Maxout是深度學習網絡中的一層網絡,就像池化層、卷積層一樣等,我們可以把maxout 看成是網絡的激活函數層,我們假設網絡某一層的輸入特徵向量為:X=(x1,x2,……xd),也就是我們輸入是d個神經元。Maxout隱藏層每個神經元的計算公式如下:
上面的公式就是maxout隱藏層神經元i的計算公式。其中,k就是maxout層所需要的參數了,由我們人為設定大小。就像dropout一樣,也有自己的參數p(每個神經元dropout概率),maxout的參數是k。公式中Z的計算公式為:
權重w是一個大小為(d,m,k)三維矩陣,b是一個大小為(m,k)的二維矩陣,這兩個就是我們需要學習的參數。如果我們設定參數k=1,那麼這個時候,網絡就類似於以前我們所學普通的MLP網絡。
我們可以這麼理解,本來傳統的MLP算法在第i層到第i+1層,參數只有一組,然而現在我們不這麼幹了,我們在這一層同時訓練n組的w、b參數,然後選擇激活值Z最大的作為下一層神經元的激活值,這個max(z)函數即充當了激活函數。
應用中如何選擇合適的激活函數?
這個問題目前沒有確定的方法,憑一些經驗吧。
1)深度學習往往需要大量時間來處理大量數據,模型的收斂速度是尤為重要的。所以,總體上來講,訓練深度學習網絡儘量使用zero-centered數據 (可以經過數據預處理實現) 和zero-centered輸出。所以要儘量選擇輸出具有zero-centered特點的激活函數以加快模型的收斂速度。
2)如果使用 ReLU,那麼一定要小心設置 learning rate,而且要注意不要讓網絡出現很多 「dead」 神經元,如果這個問題不好解決,那麼可以試試 Leaky ReLU、PReLU 或者 Maxout.
3)最好不要用 sigmoid,你可以試試 tanh,不過可以預期它的效果會比不上 ReLU 和 Maxout.