GELU (Gaussian Error Linear Unit)
GELU(高斯误差线性单元)使用标准正态分布的累积分布函数对每个输入进行缩放,是 BERT、GPT-2 和视觉 Transformer 中常用的平滑激活函数。附代码。
高斯误差线性单元(GELU)是一种激活函数,定义为 GELU(x) = x · Φ(x),其中 Φ 是标准正态分布的累积分布函数。它会根据标准正态随机变量小于某个输入值的概率对该输入加权,因此较大的正输入几乎原样通过,较大的负输入则趋近于零,接近零的输入会缩小到约一半。Dan Hendrycks 和 Kevin Gimpel 在 2016 年的论文《高斯误差线性单元(GELUs)》中提出了 GELU。GELU 成为 BERT、GPT-2、GPT-3 和视觉 Transformer(ViT)等 Transformer 模型的标准激活函数,位于每个前馈模块的两个线性层之间。
GELU 的工作原理#
Hendrycks 和 Gimpel 从随机正则化的角度推导出 GELU。可以设想将每个输入 x 乘以一个随机掩码:以 Φ(x) 的概率保留该输入,否则将其置零;这类似于丢弃法,只是保留概率会随输入增大。GELU 就是这一操作的期望值 Φ(x) · x,因此它会根据输入值平滑地控制输入,而 ReLU 则根据输入符号突变式地控制输入。
由此得到的曲线有三个对训练很重要的性质:
- 处处平滑:GELU 及其导数都是连续的,在零点没有折角,因此反向传播期间,权重的微小变化只会带来输出的微小变化。
- 非单调:对于负输入,输出会先下降,然后再回升并趋近于零;在 x ≈ −0.75 处达到约 −0.17 的最小值。
- 负输入的梯度:中等程度的负输入对应的单元仍能获得梯度,因此它们可以继续学习,而 ReLU 单元在这种情况下会停止学习。
由于 Φ 涉及误差函数,常见的近似形式有两种。tanh 形式为 0.5x(1 + tanh(√(2/π)(x + 0.044715x³))),与精确 GELU 的差值在约 0.0005 以内,曾用于 GPT-2。sigmoid 形式为 x · σ(1.702x),差值在约 0.02 以内,是 OpenAI CLIP 使用的 QuickGELU。PyTorch 的 nn.GELU 默认计算精确形式,而使用 approximate="tanh" 时则计算 tanh 形式:
import torch
from torch import nn
x = torch.tensor([-3.0, -1.0, -0.75, 0.0, 1.0, 3.0])
# Exact GELU: x * Phi(x), where Phi is the standard normal CDF
exact = nn.GELU()(x)
# Tanh approximation, as used in GPT-2
approx = nn.GELU(approximate="tanh")(x)
print(f"GELU exact: {[round(v, 4) for v in exact.tolist()]}")
print(f"GELU tanh: {[round(v, 4) for v in approx.tolist()]}")
print(f"ReLU: {nn.ReLU()(x).tolist()}")精确 GELU 会输出 [-0.004, -0.1587, -0.17, 0.0, 0.8413, 2.996],tanh 形式会输出 [-0.0036, -0.1588, -0.17, 0.0, 0.8412, 2.9964],ReLU 会输出 [0.0, 0.0, 0.0, 0.0, 1.0, 3.0]。GELU 在 −0.75 附近的最小值为 −0.17;当输入为 1 时,输出为 0.8413,因为 Φ(1) = 0.8413;在 ±3 处则几乎与 ReLU 相同。两种 GELU 形式只在小数点后第四位有所不同。
GELU 的应用场景#
- GPT 模型:OpenAI 于 2018 年推出的首个 GPT 使用了 GELU,GPT-2 和 GPT-3 也沿用了它。
- BERT:Google 的 BERT 效仿 GPT,选择了 GELU 而非 ReLU;大多数 BERT 风格的编码器仍在使用 GELU。
- 视觉 Transformer:ViT 在每个编码器模块的 MLP 中使用 GELU,许多视觉骨干网络也纷纷采用,包括 ConvNeXt;ConvNeXt 在改进 ResNet 的同时,用 GELU 替换了 ReLU。
- 检测 Transformer:在 Ultralytics 软件包中,RT-DETR 的 AIFI Transformer 编码器(百度的实时检测 Transformer)会在两个前馈层之间应用 GELU。
许多近期的大语言模型(LLMs)已从普通 GELU 转向门控前馈层。Google 的 Gemma 使用 GEGLU,即将 GELU 激活后的投影与另一个线性投影相乘;Llama、PaLM 和 Qwen 则使用基于 SiLU 的 SwiGLU。
GELU 与相关激活函数#
- ReLU:max(0, x) 计算成本更低,会输出精确的零,并且在零点有折角。GELU 论文报告称,在其测试的每一项计算机视觉、自然语言处理和语音任务中,GELU 的表现都优于 ReLU 和 ELU。
- SiLU(Swish):x · σ(x) 的整体形状相同,但最小值更低,约为 −0.28。Transformer 通常选择 GELU,而卷积检测器更常使用 SiLU。
- Leaky ReLU:对负输入保留固定的直线斜率,而 GELU 在负数一侧的曲线会回到零。
- GEGLU:这种门控变体增加了第二个学习得到的投影。在 Noam Shazeer 于 2020 年对 T5 进行的比较中,参数数量相同时,GEGLU 前馈层在留出集上的对数困惑度为 1.633,而 GELU 为 1.679,ReLU 为 1.677。










