1.介紹
在深度學習網絡中,我們經常看到卷積層之後,會接一個激活函數,而現在比較常見的激活函數有Sigmoid和Relu,那麼卷積層之後,爲什麼要接一個激活函數呢?
卷積層操作可以用y = w*x + b(其中w爲權重,b爲偏置)表示,如果我們在後面沒有接激活函數,那麼y_out = w2 * (w1 * (w0 * x + b0) + b1) + b2[假設網絡是三層],將此式子分解之後,y_out = w2 * w1 * w0 * x + w2 * w1 * b0 + w2 * b1 + b2, 當模型被訓練好之後,權重和偏置就是一個固定數,y_out 的表達式就成了一個線性表達式(y = a * x + b),很明顯,這樣的模型表達力是很弱。如果我們採樣非線性激活激活函數F,那麼y_out = F(w2 * F (w1 *F (w0 * x + b0) + b1) + b2),那麼y_out 輸出就可以幾乎模擬容易函數(中間輸出的是非線性映射值)。
2.激活函數特點
深度學習前期用到的激活函數有Sigmoid和Tanh,後期有Relu、LeakyRelu、pRelu、Elu、softplus,接下來,我將一一介紹它們的特點。
Sigmoid 函數
特點:
Sigmoid 函數可以把輸入的值映射到0到1之間,類似一種歸一化操作
缺點:
1.容易引起梯度消失(當權重初始化爲0到1之間的時候,Sigmoid 函數梯度的最大值也就爲0.25,會導致反向傳播的時候,距離輸入層的梯度值越來越小),當然也可能發生梯度爆炸(當權重比較大的時候)
2.Sigmoid 函數的輸出不是0均值,會導致梯度更新要不爲正,要不爲負,詳細證明參考:https://www.zhihu.com/question/50396271?from=profile_question_card,使得網絡很難收斂
3.計算複雜,涉及到e的指數計算,而且這個函數對於硬件化也不友好
應用場所:
將神經網絡的輸出值映射到0到1之間(乘以255就變換成了圖片RGB原始像素值範圍),作爲二分類網絡的輸出激活函數,激活函數(很少用它了)
Tanh 函數
特點:
Tanh 函數可以把輸入的值映射到-1到1之間,解決掉了Sigmoid 輸出不是0均值的問題
缺點:
1.梯度消失(爆炸)問題
2.計算複雜,涉及到e的指數計算,而且這個函數對於硬件化也不友好
應用場所:
gan中最後一層使用tanh(使得訓練更穩定),激活函數(很少用它了)
Relu函數
特點:
解決掉了梯度消失問題(當x>0的時候,梯度始終爲1),計算速度快(判斷是否大於0就行)
缺點:
1.Relu函數的輸出不是0均值
2. 會產生'Dead ReLU Problem'問題,詳細證明參考:https://blog.csdn.net/disiwei1012/article/details/79204243,其實,在我們訓練網絡的時候,很少出現這種問題,所以大膽的用吧
應用場所:
常見的激活函數,默認就選擇它吧
LeakyRelu與pRelu函數,當a=0.1的時候,可以畫出圖片中的內容
pRelu與LeakyRelu的區別在於,pRelu中的參數a是一個可學習的參數,而LeakyRelu中,a是一個固定值
特點:
LeakyRelu(pRelu)繼承了Relu所有的優點,同時也解決了'Dead ReLU Problem'問題,但實際應用中,Relu的效果沒有比它差
應用場所:
常見的激活函數,有些時候用它,會取得不錯的效果,建議還是試一下爲好
Elu函數, 當a=10的時候,可以畫出圖片中的內容
特點:
Elu繼承了Relu所有的優點,同時也解決了'Dead ReLU Problem'問題,但實際應用中,Relu的效果沒有比它差
缺點:
1.計算複雜,涉及到e的指數計算,而且這個函數對於硬件化也不友好
應用場所:
激活函數(感覺用的人並不多)
Softplus函數
特點:
Softplus相對於Relu,是一種更加平滑的激活函數
缺點:
1.計算複雜,涉及到e的指數計算,而且這個函數對於硬件化也不友好
應用場所:
激活函數(對於有些輸出,需要更加平滑和連續性,會取到意想不到的結果),我建議有時收斂不了,可以試一下它
4.代碼實現
import numpy as np
import matplotlib.pyplot as plt
'''
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_d(x):
return sigmoid(x) * (1 - sigmoid(x))
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = sigmoid(x)
p1.plot(x, y)
p1.set_title('sigmoid')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = sigmoid_d(x)
p2.plot(x, y)
p2.set_title('sigmoid_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
'''
'''
def tanh(x):
return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
def tanh_d(x):
return 1-tanh(x)*tanh(x)
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = tanh(x)
p1.plot(x, y)
p1.set_title('tanh')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = tanh_d(x)
p2.plot(x, y)
p2.set_title('tanh_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
'''
'''
def relu(x):
return np.maximum(0, x)
def relu_d(x):
x_d = x.copy()
x_d[x>=0]=1
x_d[x<0]=0
return x_d
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = relu(x)
p1.plot(x, y)
p1.set_title('relu')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = relu_d(x)
p2.plot(x, y)
p2.set_title('relu_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
'''
'''
def pRelu(x, a=0.1):
return np.maximum(a*x, x)
def pRelu_d(x, a=0.1):
x_d = x.copy()
x_d[x>=0]=1
x_d[x<0]=a
return x_d
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = pRelu(x)
p1.plot(x, y)
p1.set_title('pRelu')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = pRelu_d(x)
p2.plot(x, y)
p2.set_title('pRelu_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
'''
'''
def Elu(x, a=10):
x_copy = x.copy()
for i in range(x_copy.shape[0]):
if x_copy[i] < 0:
x_copy[i] = a * (np.exp(x_copy[i]) - 1)
return x_copy
def Elu_d(x, a=10):
x_copy = x.copy()
for i in range(x_copy.shape[0]):
if x_copy[i] < 0:
x_copy[i] = a * (np.exp(y[i]))
else:
x_copy[i] = 1
return x_copy
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = Elu(x)
p1.plot(x, y)
p1.set_title('Elu')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = Elu_d(x)
p2.plot(x, y)
p2.set_title('Elu_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
'''
def Softplus(x):
return np.log(1 + np.exp(x))
def Softplus_d(x):
return 1 / (1 + np.exp(-x))
x = np.arange(-5, 5, 0.1)
p1 = plt.subplot(211)
y = Softplus(x)
p1.plot(x, y)
p1.set_title('Softplus')
p1.axhline(0.5, ls='--', color='r')
p1.axvline(ls='--', color='r')
p2 = plt.subplot(212)
y = Softplus_d(x)
p2.plot(x, y)
p2.set_title('Softplus_d')
p2.axhline(0.5, ls='--', color='r')
p2.axvline(ls='--', color='r')
plt.subplots_adjust(hspace=1)
plt.show()