目錄
一、什麼是激活函數
如圖所示,表示神經元的O中明確顯示了激活函數的計算過程,即信號的加權總和爲節點a,然後節點a被激活函數h()轉換成節點y。簡單的說,我們可以將上圖用以下兩個函數表示:
表示先計算輸入信號的加權總和,然後用激活函數轉換這一總和。因此,登場的函數會將輸入信號的總和轉換爲輸出信號,這種函數一般稱爲激活函數(activation function)。
二、神經網絡的激活函數爲什麼必須使用非線性函數
換句話說,激活函數不能使用線性函數。爲什麼不能使用線性函數呢?
因爲使用線性函數的話,加深神經網絡的層數就沒有意義了。 線性函數的問題在於,不管如何加深層數,總是存在與之等效的“無隱藏層的神經網絡”。爲了具體地(稍微直觀地)理解這一點,我們來思考下面這個簡單的例子。
這裏我們考慮把線性函數作爲激活函數,把的運算對應3層神經網絡A。這個運算會進行 的乘法運算,但是同樣的處理可以由(注意,)這一次乘法運算(即沒有隱藏層的神經網絡)來表示。如本例所示, 使用線性函數時,無法發揮多層網絡帶來的優勢。因此,爲了發揮疊加層所帶來的優勢,激活函數必須使用非線性函數。
如果使用非線性函數的話,激活函數給神經元引入了非線性因素,使得神經網絡可以任意逼近任何非線性函數,這樣神經網絡就可以應用到衆多的非線性模型中。
三、幾種激活函數
3.1 階躍函數
公式:
1. 階躍函數的實現
當輸入超過0時,輸出1, 否則輸出0。可以像下面這樣簡單地實現階躍函數。
def step_function(x):
if x > 0:
return 1
else:
return 0
這個實現簡單、易於理解,但是參數x只能接受實數(浮點數)。也就是說,允許形如step_function(3.0)的調用,但不允許參數取NumPy數組,例如step_function(np.array([1.0, 2.0]))。爲了便於後面的操作,因此我們把它修改爲支持NumPy數組的實現。
def step_function(x):
y = x > 0
return y.astype(np.int)
上述函數的內容只有兩行。由於使用了NumPy中的“技巧”,可能會有點難理解。因此將用幾行代碼讓你更好地理解這種“技巧”。
import numpy as np
x = np.array([-1.0, 1.0, 2.0])
print(x) # [-1., 1., 2.]
y = x > 0
print(y) # [False, True, True]
Y = y.astype(np.int)
print(Y) # [0, 1, 1]
[-1. 1. 2.]
[False True True]
[0 1 1]
其中astype()方法通過參數指定期望的類型,這個例子中是np.int型。Python中將布爾型轉換爲int型後,True會轉換爲1,False會轉換爲0。以上就是階躍函數的實現中所用到的NumPy的“技巧”。
2. 階躍函數的圖形
# 導包
import numpy as np
import matplotlib.pylab as plt
# 定義階躍函數
def step_function(x):
return np.array(x > 0, dtype=np.int)
# 模擬數據
x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
# 繪圖
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # 指定y軸的範圍
plt.show()
階躍函數以0爲界,輸出從0切換爲1(或者從1切換爲0)。它的值呈階梯式變化,所以稱爲階躍函數。
3.2 sigmoid函數
公式:
1. sigmoid函數的實現
下面,用Python可以像下面代碼表示的sigmoid函數。
def sigmoid(x):
return 1 / (1 + np.exp(-x))
如果在這個sigmoid函數中輸入一個NumPy數組,結果會如何呢?
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
x = np.array([-1.0, 1.0, 2.0])
print(sigmoid(x))
[0.26894142 0.73105858 0.88079708]
之所以sigmoid函數的實現能支持NumPy數組,祕密就在於NumPy的廣播功能。根據NumPy 的廣播功能,如果在標量和NumPy數組 之間進行運算,則標量會和NumPy數組的各個元素進行運算。
2. sigmoid函數的圖形
# 導包
import numpy as np
import matplotlib.pylab as plt
# 定義sigmoid函數
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 模擬數據
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
# 繪圖
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # 指定y軸的範圍
plt.show()
縱軸的取值範圍(0, 1)。
3.3 ReLU函數
公式:
1. ReLu函數的實現
ReLU(Rectified Linear Unit)函數在輸入大於0時,直接輸出該值;在輸入小於等於0時,輸出0。因此,ReLU函數的實現也很簡單,可以寫成如下形式。
def relu(x):
return np.maximum(0, x)
這裏使用了NumPy的maximum函數。maximum函數會從輸入的數值中選擇較大的那個值進行輸出。
2. ReLu函數的圖形
# 導包
import numpy as np
import matplotlib.pylab as plt
# 定義relu函數
def relu(x):
return np.maximum(0, x)
# 模擬數據
x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
# 繪圖
plt.plot(x, y)
plt.ylim(-1, 5) # 指定y軸的範圍
plt.show()
3.4 softmax函數
公式:
softmax函數的分子是輸入信號的指數函數,分母是所有輸入信號的指數函數的和。
1. softmax函數的實現
用圖表示softmax函數的話,如圖所示,softmax函數的輸出通過箭頭與所有的輸入信號相連。輸出層的各個神經元都受到所有輸入信號的影響。
下面,用Python可以像下面代碼表示的softmax函數。
def softmax(a):
exp_a = np.exp(a)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
2. 實現softmax函數時的注意事項
上面的softmax函數的實現雖然正確描述了公式,但在計算機的運算上有一定的缺陷。這個缺陷就是溢出問題。softmax函數的實現中要進行指數函數的運算,但是此時指數函數的值很容易變得非常大。比如,的值 會超過20000,會變成一個後面有40多個0的超大值,的結果會返回一個表示無窮大的inf。如果在這些超大值之間進行除法運算,結果會出現“不確定”的情況。
softmax函數的實現可以像下式這樣進行改進。
這裏的可以使用任何值,但是爲了防止溢出,一般會使用輸入信號中的最大值。我們來看一個具體的例子。
a = np.array([1010, 1000, 990])
print(np.exp(a) / np.sum(np.exp(a))) # softmax函數的運算
c = np.max(a) # 1010
print(a - c)
print(np.exp(a - c) / np.sum(np.exp(a - c)))
[nan nan nan]
[ 0 -10 -20]
[9.99954600e-01 4.53978686e-05 2.06106005e-09]
我們發現原本爲nan(not a number,不確定)的地方,現在被正確計算了。綜上,我們可以像下面這樣實現softmax函數。
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c) # 溢出對策
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
3. softmax函數的特徵
使用softmax()函數,可以按如下方式計算神經網絡的輸出。
import numpy as np
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c) # 溢出對策
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y)
print(np.sum(y))
[0.01821127 0.24519181 0.73659691]
1.0
如上所示,softmax函數的輸出是0.0到1.0之間的實數。並且softmax函數的輸出值的總和是1。輸出總和爲1是softmax函數的一個重要性質。
正因爲有了這個性質,我們纔可以把softmax函數的輸出解釋爲“概率”。 比如,上面的例子可以解釋成y[0]的概率是0.018(1.8%),y[1]的概率是0.245(24.5%),y[2]的概率是0.737(73.7%)。從概率的結果來看,可以說“因爲第2個元素的概率最高,所以答案是第2個類別”。而且,還可以回答“有74%的概率是第2個類別,有25%的概率是第1個類別,有1%的概率是第0個類別”。也就是說,通過使用softmax函數,我們可以用概率的(統計的)方法處理問題。