🎙️ 语音朗读
当前: 晓晓 (温柔女声)
激活函数深度解析:从Sigmoid到Swish
激活函数是神经网络中引入非线性的关键组件,选择合适的激活函数对模型性能有着重要影响。
为什么需要激活函数
如果没有激活函数,无论神经网络有多少层,其输出仅仅是输入的线性组合,无法学习复杂的非线性映射:
1 | import numpy as np |
Sigmoid函数
Sigmoid是最早广泛使用的激活函数:
$$\sigma(x) = \frac{1}{1 + e^{-x}}$$
1 | def sigmoid(x): |
优点:
- 输出在(0,1)之间,可以表示概率
- 平滑可导
缺点:
- 梯度消失:当输入绝对值较大时,梯度趋近于0
- 输出非零中心化:导致后续层梯度更新缓慢
Tanh函数
$$\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}$$
1 | def tanh(x): |
Tanh是Sigmoid的改进版本,输出在(-1,1)之间,零中心化,但仍存在梯度消失问题。
ReLU函数
ReLU(Rectified Linear Unit)是目前最常用的激活函数:
$$\text{ReLU}(x) = \max(0, x)$$
1 | def relu(x): |
优点:
- 计算高效
- 正区间梯度恒为1,缓解梯度消失
- 稀疏激活
缺点:
- 神经元死亡:负区间梯度为0,可能导致神经元永久失活
Leaky ReLU
Leaky ReLU在负区间引入一个小的斜率,解决神经元死亡问题:
1 | def leaky_relu(x, alpha=0.01): |
PReLU
PReLU将负区间的斜率设为可学习参数:
1 | import torch |
ELU
ELU在负区间使用指数函数,使输出均值接近0:
1 | def elu(x, alpha=1.0): |
Swish函数
Swish是Google提出的自门控激活函数:
$$\text{Swish}(x) = x \cdot \sigma(\beta x)$$
1 | def swish(x, beta=1.0): |
研究表明,Swish在深层网络中表现优于ReLU。
GELU
GELU(Gaussian Error Linear Unit)在Transformer中被广泛使用:
1 | def gelu(x): |
激活函数选择指南
| 场景 | 推荐激活函数 |
|---|---|
| 隐藏层(通用) | ReLU |
| 隐藏层(深层网络) | Swish/GELU |
| 隐藏层(存在死亡神经元) | Leaky ReLU/PReLU |
| 输出层(二分类) | Sigmoid |
| 输出层(多分类) | Softmax |
| 输出层(回归) | 无激活/Linear |
总结
激活函数从Sigmoid发展到ReLU及其变体,再到Swish和GELU,每一次改进都解决了前一代的问题。ReLU及其变体因为计算高效和缓解梯度消失而成为隐藏层的默认选择,而Swish和GELU在Transformer等深层架构中表现更优。选择激活函数时,需要综合考虑梯度特性、计算效率和具体任务需求。