1. 程式人生 > >Tensorflow學習筆記(六)幾種常見的啟用函式介紹及用matplotlib畫圖

Tensorflow學習筆記(六)幾種常見的啟用函式介紹及用matplotlib畫圖

歷史上,sigmoid函式曾非常常用,然而現在它已經不太受歡迎,實際很少使用了,因為它主要有兩個缺點:

1. 函式飽和使梯度消失:sigmoid 神經元在值為 0 或 1的時候接近飽和,這些區域,梯度幾乎為 0。因此在反向傳播時,這個區域性梯度會與整個代價函式關於該單元輸出的梯度相乘,結果也會接近為 0 。

這樣,幾乎就沒有訊號通過神經元傳到權重再到資料了,因此這時梯度就對模型的更新沒有任何貢獻。除此之外,為了防止飽和,必須對於權重矩陣的初始化特別留意。比如,如果初始化權重過大,那麼大多數神經元將會飽和,導致網路就幾乎不學習。

2. sigmoid 函式不是關於原點中心對稱的

這個特性會導致後面網路層的輸入也不是零中心的,進而影響梯度下降的運作。

因為如果輸入都是正數的話(如 f=wTx+bf=wTx+b 中每個元素都x>0 ),那麼關於 w的梯度在反向傳播過程中,要麼全是正數,要麼全是負數(具體依據整個表示式 f而定),這將會導致梯度下降權重更新時出現 z 字型的下降。

當然,如果是按batch 去訓練,那麼每個 batch 可能得到不同的訊號,整個批量的梯度加起來後可以緩解這個問題。因此,該問題相對於上面的神經元飽和問題來說只是個小麻煩,沒有那麼嚴重。

(2)Relu

ReLU. 近年來,ReLU 變的越來越受歡迎。它的數學表示式是: f(x)=max(0,x)。很顯然,從上圖左可以看出,輸入訊號 
<0時,輸出為0,>0時,輸出等於輸入。ReLU的優缺點如下:

優點:1.相比起Sigmoid和tanh,ReLU(e.g. a factor of 6in Krizhevsky et al.)在SGD中能夠快速收斂。據稱,這是因為它線性、非飽和的形式。2.Sigmoid和tanh涉及了很多很expensive的操作(比如指數),ReLU可以更加簡單的實現。3.有效緩解了梯度消失的問題。4.在沒有無監督預訓練的時候也能有較好的表現。5.提供了神經網路的稀疏表達能力。缺點:隨著訓練的進行,可能會出現神經元死亡,權重無法更新的情況。如果發生這種情況,那麼流經神經元的梯度從這一點開始將永遠是0。也就是說,ReLU神經元在訓練中不可逆地死亡了。 ReLU在訓練的時候很”脆弱”,一不小心有可能導致神經元”壞死”。舉個例子:由於ReLU在x<0時梯度為0,這樣就導致負的梯度在這個ReLU被置零,而且這個神經元有可能再也不會被任何資料啟用。如果這個情況發生了,那麼這個神經元之後的梯度就永遠是0了,也就是ReLU神經元壞死了,不再對任何資料有所響應。實際操作中,如果你的learning rate 很大,那麼很有可能你網路中的40%的神經元都壞死了。 當然,如果你設定了一個合適的較小的learning rate,這個問題發生的情況其實也不會太頻繁。

對比sigmoid類函式主要變化是: 
1)單側抑制 
2)相對寬闊的興奮邊界 
3)稀疏啟用性。

         Leaky ReLUs 就是用來解決ReLU壞死的問題的。和ReLU不同,當x<0時,它的值不再是0,而是一個較小斜率(如0.01等)的函式。也就是說f(x)=1(x<0)(ax)+1(x>=0)(x),其中a是一個很小的常數。這樣,既修正了資料分佈,又保留了一些負軸的值,使得負軸資訊不會全部丟失。關於Leaky ReLU 的效果,眾說紛紜,沒有清晰的定論。有些人做了實驗發現 LeakyReLU 表現的很好;有些實驗則證明並不是這樣。 
- PReLU. 對於 Leaky ReLU 中的a,通常都是通過先驗知識人工賦值的。然而可以觀察到,損失函式對a的導數我們是可以求得的,可不可以將它作為一個引數進行訓練呢? Kaiming He 2015的論文《Delving Deep into Rectifiers: Surpassing Human-Level Performance onImageNet Classification》指出,不僅可以訓練,而且效果更好。原文說使用了Parametric ReLU後,最終效果比不用提高了1.03%. 
-Randomized Leaky ReLU. Randomized Leaky ReLU 是leaky ReLU 的random 版本, 其核心思想就是,在訓練過程中,a是從一個高斯分佈中隨機出來的,然後再在測試過程中進行修正。 


(3)tanh

tanh 函式同樣存在飽和問題,但它的輸出是零中心的,因此實際中 tanh 比 sigmoid 更受歡迎。                 

優點:
1.比Sigmoid函式收斂速度更快。
2.相比Sigmoid函式,其輸出以0為中心。
缺點:
還是沒有改變Sigmoid函式的最大問題——由於飽和性產生的梯度消失。

(4)ELU

ELU被定義為 f(x)={a(ex1)xif(x<0)if(0x) 其中a>0


優點:
1.ELU減少了正常梯度與單位自然梯度之間的差距,從而加快了學習。
2.在負的限制條件下能夠更有魯棒性。

另附畫圖程式,將其他一些啟用函式也畫了出來

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-10,10, 60)
def elu(x,a):
    y=[]
    for i in x:
        if i>=0:
            y.append(i)
        else:
            y.append(a*np.exp(i)-1)
    return y

relu=np.maximum(x,[0]*60)
relu6=np.minimum(np.maximum(x,[0]*60),[6]*60)
softplus=np.log(np.exp(x)+1)
elu=elu(x,1)
softsign=x/(np.abs(x)+1)
sigmoid=1/(1+np.exp(-x))
tanh=np.tanh(x)
lrelu=np.maximum(0.1*x,x)
plt.figure()#matplotlib 的 figure 就是一個 單獨的 figure 小視窗

plt.plot(x, relu6,label='relu6',linewidth=3.0)
plt.plot(x, relu,label='relu',color='black',linestyle='--',linewidth=2.0)
plt.plot(x, elu,label='elu',linewidth=2.0)
plt.plot(x, lrelu,label='lrelu',linewidth=1.0)

ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.legend(loc='best')
plt.figure()
plt.ylim((-1.2, 1.2))
plt.plot(x, softsign,label='softsign',linewidth=2.0)
plt.plot(x, sigmoid,label='sigmoid',linewidth=2.0)
plt.plot(x, tanh,label='tanh',linewidth=2.0)
plt.plot(x, softplus,label='softplus',linewidth=2.0)
# plt.plot(x, hyperbolic_tangent,label='hyperbolic_tangent',linewidth=2.0)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.legend(loc='best')
plt.show()