SiLU (Sigmoid Linear Unit)
SiLU 也称为 Swish,它将输入乘以自身的 sigmoid 值,从而得到一种平滑的自门控激活函数。内容涵盖其数学原理、起源以及与 ReLU 的比较。
Sigmoid 线性单元 (SiLU) 是一种激活函数,定义为 SiLU(x) = x · σ(x),其中 σ 是 sigmoid 函数。它几乎原样传递较大的正输入,将较大的负输入映射到接近零的值,并在两者之间平滑弯曲;其最小值约为 −0.278,出现在 x ≈ −1.278 处。SiLU 与 β = 1 时的 Swish 是同一个函数,这两个名称可以互换使用。它常作为卷积视觉模型的默认激活函数;在 SwiGLU模块中,它还用于驱动许多大语言模型 (LLM)的前馈层。
定义与性质#
SiLU 会将每个输入乘以一个门控值 σ(x),该值介于 0 和 1 之间,并由输入本身计算得出,因此称为自门控。它的导数为 σ(x) · (1 + x · (1 − σ(x))),两者共同赋予 SiLU 四种区别于 ReLU训练行为的特性:
- 处处平滑:曲线及其导数都是连续的,在零点没有折角,因此权重发生微小变化时,输出也只会微小变化,这有利于梯度下降。
- 负输入也有梯度:输入为负的单元仍能获得较小的梯度,因此可以继续学习。输入始终为负的 ReLU 单元完全没有梯度,可能永远停止学习,这种失效称为 ReLU 坏死。
- 非单调:当 x 从较大的负值上升至约 −1.28 时,输出会略微下降,之后再上升,因此该函数并非单调函数。
- 有下界、无上界:输出不会低于约 −0.278,且正输入会像使用 ReLU 时那样直接通过而不发生饱和,从而避免深层网络中 sigmoid 和 tanh 的梯度消失问题。
下面的 PyTorch 代码会计算五个点处的 SiLU 值以及 SiLU 和 ReLU 的梯度。
import torch
import torch.nn.functional as F
x = torch.tensor([-4.0, -1.28, 0.0, 1.0, 4.0], requires_grad=True)
# SiLU(x) = x * sigmoid(x),并与相同输入下的 ReLU 进行比较
silu = F.silu(x)
relu = F.relu(x)
# 各激活函数相对于其输入的梯度
silu_grad = torch.autograd.grad(silu.sum(), x)[0]
relu_grad = torch.autograd.grad(relu.sum(), x)[0]
print("SiLU output: ", [round(v, 4) for v in silu.tolist()])
print("SiLU gradient:", [round(v, 4) for v in silu_grad.tolist()])
print("ReLU gradient:", relu_grad.tolist())输出结果会显示 [-0.0719, -0.2785, 0.0, 0.7311, 3.9281] 对应的 SiLU 值、[-0.0527, -0.0003, 0.5, 0.9277, 1.0527] 对应的 SiLU 梯度,以及 [0.0, 0.0, 0.0, 1.0, 1.0] 对应的 ReLU 梯度。在 −4 处,ReLU 输出 0 且不传递梯度,而 SiLU 仍会传递 −0.0527。在 −1.28 处,SiLU 位于 −0.2785 的最小值处,梯度几乎恰好为 0;在 4 处,其梯度略大于 1。
名称的由来#
Hendrycks 和 Gimpel 在 2016 年提出 GELU的论文中,将 x · σ(x) 命名为 Sigmoid 线性单元;在论文中,它作为 GELU 的一种基于 sigmoid 的变体出现,性能不如 GELU,但通常优于 ReLU 和 ELU。2017 年,Elfwing、Uchibe 和 Doya 将 SiLU 用于神经网络函数逼近和强化学习。同年晚些时候,Google 研究人员通过自动搜索激活函数重新发现了 x · σ(βx),并将其命名为 Swish;他们报告称,将 ReLU 替换为 Swish 后,Mobile NASNet-A的 ImageNet top-1 准确率提高了 0.9%,Inception-ResNet-v2 则提高了 0.6%。PyTorch 在 1.7 版本中以早期名称加入了 nn.SiLU。
SiLU 与其他激活函数的区别#
- ReLU:max(0, x) 的计算成本更低,会产生精确的零值,并且对正输入的梯度恒为 1。SiLU 则是为换取平滑性和负值一侧的梯度,在每个元素上额外计算一次 sigmoid。
- GELU:x · Φ(x),其中 Φ 是标准正态累积分布函数。两条曲线形状相同,缩放后的 SiLU,即 x · σ(1.702x),在所有位置与 GELU 的差值都不超过约 0.02。GELU 通常用于 BERT 和 ViT 等 Transformer,而 SiLU 在基于 CNN 的检测器中更常见。
- Sigmoid:σ(x) 会将输入压缩到 0 到 1 的范围,并在两端饱和,因此可用作输出概率的输出层。SiLU 则只将 sigmoid 用作门控。
- Hard-Swish:x · ReLU6(x + 3) / 6,是随 MobileNetV3 一同提出的 SiLU 近似函数。它用分段线性门控代替 sigmoid 门控,避免在移动硬件上计算指数函数。
- SwiGLU:一种门控线性单元,将 SiLU(xW) 与第二个投影 xV 逐元素相乘。它构成了 LLaMA 及许多其他 LLM 的前馈模块。
SiLU 的应用场景#
SiLU 也称为 Swish,是 EfficientNet中的全局激活函数,在现代实时目标检测器中也很常见。Ultralytics YOLO 模型从 YOLOv5 v4.0 开始使用 SiLU;该版本于 2021 年 1 月以 SiLU 替换了 LeakyReLU 和 Hardswish。在 YOLO26中,每个 Conv 模块都由一个卷积、批量归一化和 SiLU 组成。










