激活函數
各激活函數曲線對比
常用激活函數:
tf.sigmoid()
tf.tanh()
tf.nn.relu()
tf.nn.softplus()
tf.nn.softmax()
tf.nn.dropout()
tf.nn.elu()
import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import derivative
def sigmoid(x):
y = 1 / (1 + np.exp(-x))
return y
def tanh(x):
return (np.exp(x) - np.exp(-x)) / (np.exp(x)+np.exp(-x))
def relu(x):
return [max(xi,0) for xi in x]
def elu(x,a=1):
y = []
for xi in x:
if xi >= 0:
y.append(xi)
else:
y.append(a*(np.exp(xi)-1))
return y
def softplus(x):
return np.log(1+np.exp(x))
def derivative_f(func,input,dx=1e-6):
y = [derivative(func,x,dx) for x in input]
return y
x = np.linspace(-5,5,1000)
flg = plt.figure(figsize=(15,5))
ax1 = flg.add_subplot(1,2,1)
ax1.axis([-5,5,-1,1])
plt.xlabel(r'active function',fontsize=18)
ax1.plot(x,sigmoid(x),'r-',label='sigmoid')
ax1.plot(x,tanh(x),'g--',label='tanh')
ax1.plot(x,relu(x),'b-',lw=1,label='relu')
ax1.plot(x,softplus(x),'y--',label='softplus')
ax1.plot(x,elu(x),'b--',label='elu')
ax1.legend()
ax2 = flg.add_subplot(1,2,2)
plt.xlabel(r'derivative',fontsize=18)
ax2.plot(x,derivative_f(sigmoid,x),'r-',label='sigmoid')
ax2.plot(x,derivative_f(tanh,x),'g--',label='tanh')
ax2.plot(x,derivative_f(softplus,x),'y-',label='softplus')
ax2.legend()
plt.show()
各激活函數優缺點
sigmoid函數
優點:在於輸出映射在(0,1)范圍內,單調連續,適合用作輸出層,求導容易
缺點:一旦輸入落入飽和區,一階導數接近0,就可能產生梯度消失的情況
tanh函數
優點:輸出以0為中心,收斂速度比sigmoid函數要快
缺點:存在梯度消失問題
relu函數
優點:目前最受歡迎的激活函數,在x<0時,硬飽和,在x>0時,導數為1,所以在x>0時保持梯度不衰減,從而可以緩解梯度消失的問題,能更快收斂,並提供神經網絡的稀疏表達能力
缺點:隨着訓練的進行,部分輸入或落入硬飽和區,導致無法更新權重,稱為‘神經元死亡’
elu函數
優點:有一個非零梯度,這樣可以避免單元消失的問題
缺點:計算速度比relu和它的變種慢,但是在訓練過程中可以通過更快的收斂速度來彌補
softplus函數
該函數對relu做了平滑處理,更接近腦神經元的激活模型
softmax函數
除了用於二分類還可以用於多分類,將各個神經元的輸出映射到(0,1空間)
dropout函數
tf.nn.dropout(x,keep_prob,noise_shape=None,seed=None,name=None)
一個神經元以概率keep_prob決定是否被抑制,如果被抑制,神經元的輸出為0,如果不被抑制,該神經元將被放大到原來的1/keep_prob倍,默認情況下,每個神經元是否被抑制是相互獨立的
一般規則
當輸入數據特征相差明顯時,用tanh效果很好,當特征相差不明顯時用sigmoid效果比較好,sigmoid和tanh作為激活函數需要對輸入進行規范化,否則激活后的值進入平坦區,而relu不會出現這種情況,有時也不需要輸入規范化,因此85%-90%的神經網絡會使用relu函數
損失函數
sigmoid_cross_entropy_with_logits函數
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None)
該函數不僅可以用於二分類,也可以用於多分類,例如:判斷圖片中是否包含幾種動物中的一種或多種
二分類logstic損失函數梯度推導
二項邏輯斯蒂回歸模型是一種分類模型,由條件概率p(y|x)表示,形式未參數化的邏輯斯蒂分布,這里的變量X為實數,隨機變量y取值為1或0,邏輯斯蒂模型條件概率分布如下:$$p(y=1|x) = \frac{\exp(w{\bullet}x+b)}{1+\exp(w{\bullet}x+b)}$$
\[p(y=0|x) = \frac{1}{1+\exp(w{\bullet}x+b)} \]
假設$$p(y = 1|x) = \theta(x),p(y=0|x) = 1 - \theta(x)$$
損失函數:$$L(\theta(x)) = -\prod_{i=1}^N[\theta(x_i)]^{y_i}[1-\theta(x_i)]^{1-y_i}$$
對數似然函數:$$L(\theta(x)) = -\sum_{i=1}^Ny_i * \log\theta(x_i)+(1-y_i)\log(1-\theta(x_i))$$
求\(L(\theta(x))\)的極大值,得到w的估計值,由於\(L(\theta(x))\)為凸函數,可以直接求損失函數的一階偏導:
\[\frac{\delta{L}}{\delta{w_j}} = -\sum_{i=1}^N[y_i*\frac{1}{\theta(x_i)} - (1-y_i)*\frac{1}{1-\theta(x_i)}] *\frac{\delta{\theta(x)}}{\delta{w_j}} \]
由於\(\frac{\delta{\theta(x)}}{\delta{w}} = \theta(x_i) * (1 - \theta(x_i))*x_j^i\)
得到:$$\frac{\delta{L}}{\delta{w_j}} = -\sum_{i=1}^N(y_i-\theta(x_i))*x_j^i$$
weighted_cross_entropy_with_logits函數
tf.nn.weighted_cross_entropy_with_logits(targets,logits,pos_weight,name=None)
pos_weight正樣本的一個系數
該函數在sigmoid_cross_entropy_with_logits函數的基礎上為每個正樣本添加了一個權重,其損失函數如下:
\[loss_{ij} = -[post_{weight}p_{ij}\log p_{ij}+(1-p_{ij})\log (1-p_{ij})] \]
softmax_cross_entropy_with_logits函數
tf.nn.softmax_cross_entropy_with_logits(_sentinel,labels,logits,name)
適用於每個類別相互獨立且排斥的情況,例如,判斷的圖片只能屬於一個種類而不能同時包含多個種類
損失函數:
\[logits_{ij} = \frac{e^{logits_{ij}}}{\sum_{j=0}^{numclass-1}e^{logits_{ij}}} \]
\[loss_{i} = -\sum_{j=0}^{numclass-1}label_{ij}\log (logits_{ij}) \]
sparse_softmax_cross_entropy_with_logits函數
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel,labels,logits,name)
該函數與softmax_cross_entropy_with_logits的唯一區別在於labels,該函數的標簽要求排他性的即只有一個正確類型,labels的形狀要求是[batch_size]而值必須是從0開始編碼的int32或int64,而且范圍是[0,num_class],該函數沒用過