激活函数的角色
激活函数是神经网络中引入非线性的关键组件。没有激活函数,多层线性变换的堆叠等价于单层线性变换——网络的表达能力将被严重限制。激活函数的选择直接影响模型的训练动态、收敛速度和最终性能。
在LLM时代,激活函数的演进从ReLU到GELU再到SwiGLU,每一步都带来了可测量的性能提升。
ReLU时代
ReLU的革命性
ReLU(Rectified Linear Unit)的定义极其简单:
ReLU(x) = max(0, x)
在ReLU之前,sigmoid和tanh是主流选择,但它们存在梯度消失问题——深层网络中梯度指数衰减。ReLU的梯度在正区间恒为1,有效解决了梯度消失问题,使得深层网络的训练成为可能。
ReLU的缺陷
Dead ReLU问题:当输入持续为负时,ReLU的梯度为零,神经元将永久"死亡"无法恢复。这在学习率设置不当时尤为严重。
非零中心化:ReLU的输出始终非负,导致后续层的输入分布偏向正方向,影响梯度下降效率。
Leaky ReLU与变体
为解决Dead ReLU问题,多种变体被提出:
def leaky_relu(x, negative_slope=0.01):
"""Leaky ReLU: 负区间保留小梯度"""
return torch.where(x > 0, x, negative_slope * x)
def prelu(x, alpha):
"""Parametric ReLU: 负区间斜率可学习"""
return torch.where(x > 0, x, alpha * x)
def elu(x, alpha=1.0):
"""ELU: 负区间平滑过渡到指数"""
return torch.where(x > 0, x, alpha * (torch.exp(x) - 1))
这些变体在CV领域有一定应用,但在LLM中几乎未被采用——LLM的激活函数走上了另一条路。
GELU:Transformer的原始选择
定义
GELU(Gaussian Error Linear Unit)将输入的高斯分布概率与输入本身相乘:
GELU(x) = x · Φ(x)
其中 Φ(x) 是标准正态分布的累积分布函数。实践中常使用近似:
def gelu(x):
"""精确GELU"""
return 0.5 * x * (1 + torch.erf(x / math.sqrt(2)))
def gelu_tanh_approx(x):
"""tanh近似(更快)"""
return 0.5 * x * (1 + torch.tanh(math.sqrt(2/math.pi) * (x + 0.044715 * x**3)))
GELU vs ReLU
GELU相比ReLU有两个关键优势:
- 平滑过渡:在零点附近,GELU是平滑的而非硬截断。这使得梯度更连续,训练更稳定
- 随机正则化:GELU隐含了一种随机dropout机制——输入越大,被保留的概率越高。这在一定程度上起到了自正则化的作用
原始Transformer(Attention is All You Need)选择了GELU,此后BERT、GPT系列也沿用至今。
SwiGLU:现代LLM的标配
GLU家族
GLU(Gated Linear Units)引入了门控机制:
GLU(x) = (xW + b) ⊗ σ(xV + c)
其中 σ 是sigmoid函数,⊗ 是逐元素乘法。GLU用一个"门"来控制信息的通过量。
SwiGLU的定义
SwiGLU将GLU中的sigmoid替换为Swish激活函数:
SwiGLU(x, W, V) = Swish(xW) ⊗ (xV)
Swish(x) = x · σ(x)
class SwiGLU(nn.Module):
def __init__(self, d_model, d_ff):
super().__init__()
self.w_gate = nn.Linear(d_model, d_ff, bias=False)
self.w_up = nn.Linear(d_model, d_ff, bias=False)
self.w_down = nn.Linear(d_ff, d_model, bias=False)
def forward(self, x):
gate = self.w_gate(x)
up = self.w_up(x)
# Swish门控
activated = F.silu(gate) * up # silu = swish
return self.w_down(activated)
SwiGLU的优势
- 门控机制:信息流由门控动态调节,增强了模型的表达能力
- Swish平滑性:Swish继承了GELU的平滑特性,训练稳定
- 稀疏激活:门控机制自然产生稀疏激活,类似于隐式的MoE
为什么SwiGLU取代了GELU?
PaLM、LLaMA、Qwen等2026年的主流LLM几乎都采用了SwiGLU。研究表明,在相同参数预算下,SwiGLU比GELU的困惑度低约0.1-0.3。虽然提升看似不大,但在大模型规模下,这0.1的改进相当于显著的计算资源节省。
需要注意的是,SwiGLU比标准GELU FFN多一个线性投影(从d_model到d_ff),因此参数量略多。实践中通常将d_ff缩小为原来的2/3来保持参数量一致。
其他值得关注的激活函数
Mish
Mish(x) = x · tanh(softplus(x))
Mish在零点附近更平滑,且在负区间保留了部分梯度。在CV任务中表现优异,但在LLM中尚未广泛采用。
ReGLU
ReGLU(x, W, V) = ReLU(xW) ⊗ (xV)
用ReLU替代Swish作为门控函数。比SwiGLU计算更简单,但性能略差。
GeGLU
GeGLU(x, W, V) = GELU(xW) ⊗ (xV)
用GELU作为门控。性能介于ReGLU和SwiGLU之间。
激活函数的选择指南
按任务类型
| 模型类型 | 推荐激活函数 | 理由 |
|---|---|---|
| CNN(分类) | ReLU/Mish | 简单高效,CV任务验证充分 |
| RNN/LSTM | tanh | 输出范围[-1,1],适合递归 |
| Transformer (FFN) | SwiGLU | 2026年最佳实践 |
| Transformer (旧) | GELU | 兼容性需求 |
| MoE Expert | SwiGLU | 与密集模型一致 |
按性能需求
- 追求最高性能:SwiGLU
- 追求推理速度:ReLU(计算最简单)
- 追求训练稳定:GELU或SwiGLU
- 兼容旧框架:GELU
2026年前沿方向
学习型激活函数
让网络自动学习最优激活函数:
class LearnableActivation(nn.Module):
def __init__(self, n_parameters=16):
super().__init__()
self.control_points = nn.Parameter(torch.randn(n_parameters))
def forward(self, x):
# 使用样条插值实现连续激活函数
return spline_interpolation(x, self.control_points)
稀疏激活函数
专门为稀疏计算设计的激活函数,在MoE场景下特别有意义:
def sparse_swish(x, threshold=0.1):
"""带阈值门控的稀疏Swish"""
swish = x * torch.sigmoid(x)
return torch.where(swish.abs() > threshold, swish, torch.zeros_like(swish))
上下文感知激活
激活函数的参数随上下文变化——不同层、不同位置使用不同的激活策略:
class ContextAwareActivation(nn.Module):
def __init__(self, d_model, n_activations=4):
super().__init__()
self.router = nn.Linear(d_model, n_activations)
self.activations = [
F.silu, F.gelu, F.relu, lambda x: x * torch.sigmoid(x)
]
def forward(self, x):
weights = F.softmax(self.router(x.mean(dim=-1, keepdim=True)), dim=-1)
outputs = [act(x) for act in self.activations]
return sum(w * o for w, o in zip(weights.unbind(-1), outputs))
工程实现注意事项
- 融合Kernel:将激活函数与前一线性层融合到同一个CUDA kernel中,减少显存读写
- 精度选择:在FP16/BF16训练中,激活函数的中间计算建议在FP32下进行以避免数值问题
- 内存占用:GLU系列激活函数需要存储两个分支的中间结果,梯度检查点策略需相应调整
- 推理优化:推理时Swish的sigmoid可以用查表近似,减少计算开销
结语
激活函数看似是深度学习中最"微小"的组件,但其影响深远。从ReLU到SwiGLU的演进,每一步都凝聚了对训练动态和信息流的深入理解。在AGI系统的构建中,选择正确的激活函数是确保模型性能和训练稳定性的基础。
加入讨论
这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。