深度學習-啟用函式
阿新 • • 發佈:2018-12-18
啟用函式總結
- 作用: 啟用函式給神經元引入了非線性因素,使得神經網路可以任意逼近任何非線性函式,這樣神經網路就可以應用到眾多的非線性模型中
sigmod函式(Logistic函式)
-
公式
-
求導
-
優點:
- Sigmoid函式的輸出對映在(0,1)之間,單調連續,輸出範圍有限,優化穩定,可以用作輸出層
- 求導容易
-
缺點:
- 由於其軟飽和性,容易產生梯度消失,導致訓練出現問題
- 其輸出並不是以0為中心的,使權重更新效率降低
- sigmod函式要進行指數運算,這個對於計算機來說是比較慢的
- sigmod函式飽和性:啟用函式計算量大,反向傳播求誤差梯度時,求導涉及除法反向傳播時,很容易就會出現梯度消失的情況,從而無法完成深層網路的訓練
tanh函式(雙曲正切函式)
- 簡介:tanh是雙曲正切函式,tanh函式和sigmod函式的曲線是比較相近的,咱們來比較一下看看。首先相同的是,這兩個函式在輸入很大或是很小的時候,輸出都幾乎平滑,梯度很小,不利於權重更新;不同的是輸出區間,tanh的輸出區間是在(-1,1)之間,而且整個函式是以0為中心的,這個特點比sigmod的好
- 公式
- 其中:
- 求導
- 優點:
- 比Sigmoid函式收斂速度更快
- 相比Sigmoid函式,其輸出以0為中心
- 缺點:
- 還是沒有改變Sigmoid函式的最大問題——由於飽和性產生的梯度消失
- 用法:
- 一般二分類問題中,隱藏層用tanh函式,輸出層用sigmod函式
Relu函式(線性整流函式)
-
公式
-
求導
-
優點
- 在輸入為正數的時候,不存在梯度飽和問題。
- 計算速度要快很多。ReLU函式只有線性關係,不管是前向傳播還是反向傳播,都比sigmod和tanh要快很多。(sigmod和tanh要計算指數,計算速度會比較慢)
-
缺點
- 當輸入是負數的時候,ReLU是完全不被啟用的,這就表明一旦輸入到了負數,ReLU就會死掉。這樣在前向傳播過程中,還不算什麼問題,有的區域是敏感的,有的是不敏感的。但是到了反向傳播過程中,輸入負數,梯度就會完全到0,這個和sigmod函式、tanh函式有一樣的問題
- 我們發現ReLU函式的輸出要麼是0,要麼是正數,這也就是說,ReLU函式也不是以0為中心的函式
code
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10,10)
y_sigmoid = 1/(1+np.exp(-x))
y_sigmoid_d = y_sigmoid*(1-y_sigmoid)
y_tanh = (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
y_tanh_d = 1-y_tanh*y_tanh
y_relu = np.array([0*item if item<0 else item for item in x ])
y_relu_d = np.array([0*item if item<0 else 1 for item in x ])
fig = plt.figure()
# plot sigmoid
ax = fig.add_subplot(321)
ax.plot(x,y_sigmoid)
ax.grid()
ax.set_title('Sigmoid')
# plot sigmoid_d
ax = fig.add_subplot(322)
ax.plot(x,y_sigmoid_d)
ax.grid()
ax.set_title('sigmoid_d')
# plot tanh
ax = fig.add_subplot(323)
ax.plot(x,y_tanh)
ax.grid()
ax.set_title('y_tanh')
# plot tanh
ax = fig.add_subplot(324)
ax.plot(x,y_tanh_d)
ax.grid()
ax.set_title('y_tanh_d')
# plot relu
ax = fig.add_subplot(325)
ax.plot(x,y_relu)
ax.grid()
ax.set_title('ReLu')
# plot relu
ax = fig.add_subplot(326)
ax.plot(x,y_relu_d)
ax.grid()
ax.set_title('ReLu_d')
#plot leaky relu
# ax = fig.add_subplot(121)
# y_relu = np.array([0.2*item if item<0 else item for item in x ])
# ax.plot(x,y_relu)
# ax.grid()
# ax.set_title('Leaky ReLu')
# #plot leaky relu
# ax = fig.add_subplot(122)
# y_relu = np.array([0 if item<0 else 1 for item in x ])
# ax.plot(x,y_relu)
# ax.grid()
# ax.set_title('Leaky ReLu d')
plt.tight_layout()
plt.savefig('att_d.jpg')
plt.show()