終于把神經網絡中的激活函數搞懂了!??!
今天給大家分享神經網絡中的一個關鍵概念,激活函數
激活函數是神經網絡中的核心組件之一,其主要作用是在每個神經元中為輸入信號提供非線性變換。如果沒有激活函數,神經網絡將充當簡單的線性模型。
激活函數的作用
激活函數的引入使得神經網絡可以學習和表示復雜的非線性關系,從而解決一些線性模型無法處理的問題。
圖片
- 非線性化
神經網絡的每一層通常是線性運算(如線性變換),如果不加入激活函數,整個網絡將只是線性模型的堆疊,無論多少層都仍是線性的。
激活函數通過引入非線性因素,使網絡能夠逼近任意復雜的非線性函數。 - 控制神經元的激活
激活函數對輸入信號進行處理后輸出,控制著每個神經元的激活程度。
某些激活函數會將輸出壓縮到一定范圍內,從而使網絡的輸出更加穩定。 - 梯度傳遞
在反向傳播中,激活函數還會影響梯度的傳遞。
合適的激活函數能夠使梯度在網絡中有效傳播,避免梯度消失或爆炸的問題(如 ReLU 激活函數在深度網絡中有顯著優勢)。
常見的激活函數
下面,我們一起來看一下神經網絡中常見的激活函數。
1.Sigmoid
Sigmoid 是一種 S 形曲線函數,將輸入壓縮到 (0,1) 之間,通常用于二分類問題。
圖片
優點
- 將輸入值映射到 (0, 1) 范圍內,非常適合二分類問題中的概率輸出。
缺點
- 容易出現梯度消失問題,在反向傳播中,當輸入較大或較小時,導數趨近于零,使得梯度傳遞較慢,導致深層網絡的訓練效率降低。
- 不以零為中心,導致梯度更新不平衡。
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
2.Tanh
Tanh 是 Sigmoid 的改進版本,輸出范圍在 (-1, 1),對稱于零。
圖片
優點
- 輸出范圍在 (-1, 1) 之間,使得正負值更加均衡,適合用作隱藏層的激活函數。
- 零點對稱,可以更好地解決梯度消失問題,收斂速度比 Sigmoid 更快。
缺點
- 在輸入值較大或較小時,依然存在梯度消失的問題,導致深層網絡的訓練困難。
def tanh(x):
return np.tanh(x)
3.ReLU
ReLU 是最常用的激活函數之一,對正數直接輸出,對負數輸出零。
圖片
優點
- 簡單高效,且在正數區梯度始終為 1,能夠緩解梯度消失問題。
- 計算速度快,常用于深層神經網絡。
缺點
- 存在“死亡神經元”問題,輸入為負時輸出為零,可能導致某些神經元永遠不被激活。
def relu(x):
return np.maximum(0, x)
4.Leaky ReLU
Leaky ReLU 是 ReLU 的改進版,負數區域的輸出為輸入的一個小比例,以解決“死亡神經元”問題。
圖片
其中 是一個很小的正數,通常取 0.01。
優點
- 保留負數區域的小梯度,減少神經元死亡的風險。
- 保持 ReLU 的大部分優勢。
缺點
- 引入了一個額外的參數 ,需要手動設置。
def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)
5.PReLU
PReLU 是 Leaky ReLU 的變體,負區域的斜率參數 可以在訓練中自動學習。
圖片
優點
- 負區域的斜率參數 可學習,模型能夠自動適應數據特性。
缺點
- 增加了模型復雜性和計算成本,因為需要學習額外的參數。
def prelu(x, alpha):
return np.where(x > 0, x, alpha * x)
6.ELU
ELU 是 ReLU 的另一種改進版本,ELU 在正值區域與 ReLU 相同,但在負值區域應用指數函數進行變換。
圖片
優點
- 在負區域輸出接近零,有助于加快收斂。
- 可以減少梯度消失的現象。
缺點
- 計算開銷較高,不如 ReLU 高效。
def elu(x, alpha=1.0):
return np.where(x > 0, x, alpha * (np.exp(x) - 1))
7.Swish
Swish 是一種平滑的激活函數,常常在深層網絡中表現優于 ReLU 和 Sigmoid。
圖片
其中 是 Sigmoid 函數。
優點
- 平滑且輸出無界,有更好的梯度流動性質,性能上往往優于 ReLU。
- 在深層神經網絡中表現良好,可以提高模型準確性。
缺點
- 計算量大于 ReLU,尤其在大規模神經網絡中。
def swish(x):
return x * sigmoid(x)
8.Softmax
Softmax 通常用于多分類任務的輸出層,將輸出值歸一化到 [0, 1] 范圍,總和為 1,可以理解為概率分布。
圖片
優點
- 將輸出值轉換為概率,便于多分類任務。
- 可以通過最大值索引確定類別。
缺點
- 僅適合用于輸出層,而不適合隱藏層。
- 對輸入值的極端變化敏感。
def softmax(x):
exp_x = np.exp(x - np.max(x)) # 減去最大值避免指數爆炸
return exp_x / np.sum(exp_x, axis=0)