import torch import torch.nn.functional as F from torch.autograd import Variable import matplotlib.pyplot as plt x = torch.linspace(-5, 5, 200) # 構造一段連續的數據 x = Variable(x) # 轉換成張量 x_np = x.data.numpy() #plt中形式需要numoy形式,tensor形式會報錯
一:激活函數:
- 非線性: 當激活函數是線性的時候,一個兩層的神經網絡就可以逼近基本上所有的函數了。但是,如果激活函數是恆等激活函數的時候(即f(x)=x),就不滿足這個性質了,而且如果MLP使用的是恆等激活函數,那么其實整個網絡跟單層神經網絡是等價的。
- 可微性: 當優化方法是基於梯度的時候,這個性質是必須的。
- 單調性: 當激活函數是單調的時候,單層網絡能夠保證是凸函數。
- f(x)≈x: 當激活函數滿足這個性質的時候,如果參數的初始化是random的很小的值,那么神經網絡的訓練將會很高效;如果不滿足這個性質,那么就需要很用心的去設置初始值。
- 輸出值的范圍: 當激活函數輸出值是 有限 的時候,基於梯度的優化方法會更加 穩定,因為特征的表示受有限權值的影響更顯著;當激活函數的輸出是 無限 的時候,模型的訓練會更加高效,不過在這種情況小,一般需要更小的learning rate
3:常用的激活函數
早期研究神經網絡主要采用sigmoid函數或者tanh函數,輸出有界,很容易充當下一層的輸入。近些年Relu函數及其改進型(如Leaky-ReLU、P-ReLU、R-ReLU等)在多層神經網絡中應用比較多。下面我們來總結下這些激活函數:
- 3.1單極性 sigmod函數
3.1.1:Sigmoid 是常用的非線性的激活函數,該函數是將取值為 (−∞,+∞)(−∞,+∞) 的數映射到 (0,1)之間,它的數學形式和圖像如下:
3.1.2:特點:
sigmod激勵函數符合實際,當輸入很小時,輸出接近於0;當輸入很大時,輸出值接近1,但是sigmoid函數作為非線性激活函數,但是其並不被經常使用,它具有以下幾個缺點:
1)當 zz 值非常大或者非常小時,通過右上圖我們可以看到,sigmoid函數的導數 g′(z)g′(z) 將接近 0 。這會導致權重 WW 的梯度將接近 0 ,使得梯度更新十分緩慢,即梯度消失。
2)非零中心化,也就是當輸入為0時,輸出不為0,,因為每一層的輸出都要作為下一層的輸入,而未0中心化會直接影響梯度下降 。
3)計算量比較大。
sigmoid函數可用在網絡最后一層,作為輸出層進行二分類,盡量不要使用在隱藏層。
3.1.3:pytorch實現:
y_sigmoid = F.sigmoid(x).data.numpy() #初始化已經在上面實現 plt.plot(x_np, y_sigmoid, c='red', label='sigmoid') plt.ylim((-0.2, 1.2)) plt.legend(loc='best') #圖例名稱自動選擇最佳展示位置 plt.show() #展示圖片和上面(中)類似
- 3.2:雙極性tanh函數
3.2.1 :該函數是將取值為 (−∞,+∞)(−∞,+∞) 的數映射到 (−1,1)(−1,1) 之間,其數學形式與圖形為:
3.2.2:特點:
1)tanh函數在 0 附近很短一段區域內可看做線性的。由於tanh函數均值為 0 ,因此彌補了sigmoid函數均值為 0.5 的缺點。
2)當z為非常大或者非常小的時候,由導數推斷公式可知,此時導數接近與0,會導致梯度很小,權重更新非常緩慢,即梯度消失問題。
3)冪運算問題仍然存在,計算量比較大。
3.2.3:pytorch實現:
y_tanh = F.tanh(x).data.numpy() #初始化在上面已經給出 plt.plot(x_np, y_tanh, c='red', label='tanh') plt.ylim((-1.2, 1.2)) plt.legend(loc='best') plt.show()#展示圖片和上圖(中)相似。
- 3.3:Relu函數
3.3.1 :又稱修正線性單元,是一種分段線性函數,其彌補了sigmoid函數以及tanh函數的梯度消失問題。ReLU函數的公式以及圖形,導數公式如下:
3.3.2:特點:
1)(1)在輸入為正數的時候(對於大多數輸入 zz 空間來說),不存在梯度消失問題。
(2) 計算速度要快很多。ReLU函數只有線性關系,不管是前向傳播還是反向傳播,都比sigmod和tanh要快很多。(sigmod和tanh要計算指數,計算速度會比較慢)
(3)當輸入為負時,梯度為0,會產生梯度消失問題
ReLU目前仍是最常用的activation function,在搭建人工神經網絡的時候推薦優先嘗試!
3.3.3:pytorch實現:
y_relu = F.relu(x).data.numpy() plt.plot(x_np, y_relu, c='red', label='relu') plt.ylim((-1, 5)) plt.legend(loc='best') plt.show()
- 3.4:Leaky Relu函數
3.4.1:這是一種對ReLU函數改進的函數,又稱為PReLU函數,但其並不常用。其公式與圖形如下:(a取值在(0,1)之間)
特點:
Leaky ReLU函數解決了ReLU函數在輸入為負的情況下產生的梯度消失問題。
理論上來講,Leaky ReLU有ReLU的所有優點,外加不會有Dead ReLU問題,但是在實際操作當中,並沒有完全證明Leaky ReLU總是好於ReLU。
3.5:softplus函數
3.5.1:和relu一樣為近似生物神經激活函數,函數數學形式和圖像如下:(log里面加1是為了避免非0出現)
3.5.2:特點:
1)softplus可以看作是ReLu的平滑。
3.5.3:pytorch實現:
y_softplus = F.softplus(x).data.numpy() plt.plot(x_np, y_softplus, c='red', label='softplus') plt.ylim((-0.2, 6)) plt.legend(loc='best') plt.show()
4:怎么樣去選擇激勵函數
1)在少量層結構中, 我們可以嘗試很多種不同的激勵函數. 在卷積神經網絡 Convolutional neural networks 的卷積層中, 推薦的激勵函數是 relu. 在循環神經網絡中 recurrent neural networks, 推薦的是 tanh 或者是 relu 。
2)如果使用 ReLU,那么一定要小心設置 learning rate,而且要注意不要讓網絡出現很多 “dead” 神經元,如果這個問題不好解決,那么可以試試 Leaky ReLU、PReLU 或者 Maxout.
3)Relu->Lecky Relu/Elu>tanh>sigmoid
5:參考文獻: