Sigmoid
sigmoid 函数将任意实数映射到 0 到 1 之间的值。内容涵盖其公式、梯度、概率输出、门控机制和 PyTorch 代码。
sigmoid 函数 σ(x) = 1 / (1 + e^(−x)) 沿 S 形曲线将任意实数映射到 0 和 1 之间:较大的负输入会产生接近 0 的输出,较大的正输入会产生接近 1 的输出,输入为 0 时则恰好输出 0.5。在机器学习 (ML)中,“sigmoid”几乎总是指这个 logistic 函数,也就是在逻辑回归中将线性分数转换为概率的同一条曲线。在神经网络 (NN)中,sigmoid 有三种用途:它最初是隐藏层的激活函数,可以将最终分数转换为二分类和多标签输出的概率,还可以作为循环单元和其他门控层中的软开关。后来,隐藏层改用了 ReLU 等函数,因此当前模型中的 sigmoid 大多位于输出层和门控结构中。
公式与性质#
Sigmoid 关于其中点对称,满足 σ(−x) = 1 − σ(x);它的反函数是 logit 函数 log(p / (1 − p)),可将概率转换回对数几率。因此,网络在 sigmoid 之前的原始输出称为 logit。它的导数形式简洁:σ′(x) = σ(x)(1 − σ(x));当 x = 0 时,导数达到峰值 0.25,随着曲线在两端变平,导数趋向于零,这种行为称为饱和。下面的 PyTorch 代码片段会计算五个点处的输出和梯度:
import torch
x = torch.tensor([-6.0, -2.0, 0.0, 2.0, 6.0], requires_grad=True)
y = torch.sigmoid(x)
# Backpropagate to get the derivative sigmoid(x) * (1 - sigmoid(x)) at each input
y.sum().backward()
print(f"Sigmoid: {[round(v, 4) for v in y.tolist()]}")
print(f"Gradient: {[round(v, 4) for v in x.grad.tolist()]}")输出结果会显示 [0.0025, 0.1192, 0.5, 0.8808, 0.9975] 对应的 sigmoid 值和 [0.0025, 0.105, 0.25, 0.105, 0.0025] 对应的梯度。在 ±6 处,输出与极限值的差小于 0.0025,梯度比零点处小 100 倍,因此该范围内的输入几乎不会改变产生它的权重。
隐藏层中的 Sigmoid#
早期的多层网络在每个隐藏层中都使用 sigmoid,这会导致两个问题。反向传播会将每层的一个激活函数导数相乘,而 sigmoid 的导数永远不会超过 0.25,因此经过十个 sigmoid 层后,仅这些导数就会将梯度缩放至最多 0.25¹⁰,也就是不到百万分之一,这就是梯度消失问题。sigmoid 的输出也始终为正,因此每次更新时,接收这些输出的神经元的所有权重梯度符号相同,权重只能以之字形方式趋近最优值。Tanh的输出以零为中心;Xavier Glorot 和 Yoshua Bengio在 2010 年指出,sigmoid 的正均值会使随机初始化的深度网络顶层隐藏层进入饱和状态。ReLU解决了这两个问题,并成为隐藏层的默认选择;SiLU等平滑的后续函数 x · σ(x) 仍然会在内部使用 sigmoid 作为门控。
作为输出层的 Sigmoid#
对于二元分类,单个输出 z 会转化为 p = σ(z),即正类的预测概率;对 p 使用 0.5 阈值,等价于对 z 使用 0 阈值。训练时,Sigmoid 与二元交叉熵配合使用,其相对于 logit 的梯度就是 p − y,即预测概率减去标签。框架会将两者融合以提高数值稳定性:PyTorch 的 BCEWithLogitsLoss接收原始 logits,并在内部使用 log-sum-exp 技巧,避免对已舍入为恰好 0 或 1 的概率取对数。
如果标签可以同时出现,模型会为每个标签使用一个 sigmoid,这种设置称为多标签分类。相比之下,Softmax会让类别竞争同一个概率单位,因此适用于互斥标签:
import torch
# Logits from a classifier for the labels "person", "backpack", and "car"
logits = torch.tensor([2.0, 1.5, -3.0])
# Sigmoid scores each label on its own; softmax makes the labels compete for one total
sigmoid_probs = torch.sigmoid(logits)
softmax_probs = torch.softmax(logits, dim=0)
print(f"Sigmoid: {[round(p, 3) for p in sigmoid_probs.tolist()]}, sum {sigmoid_probs.sum():.3f}")
print(f"Softmax: {[round(p, 3) for p in softmax_probs.tolist()]}, sum {softmax_probs.sum():.3f}")sigmoid 分数 [0.881, 0.818, 0.047] 的总和为 1.746,因此“person”和“backpack”都超过 0.5;而 softmax 会将相同的 logits 拆分为 [0.62, 0.376, 0.004],只有“person”仍高于 0.5。YOLO26 检测模型使用独立 sigmoid 对每个类别进行评分,并通过 BCEWithLogitsLoss 进行训练,因此一个边界框的类别分数之和不一定为 1;YOLO26 姿态模型则对每个关键点的可见性 logit 应用 sigmoid,以输出该关键点可见的概率。
作为门控的 Sigmoid#
由于 sigmoid 的输出介于 0 和 1 之间,它可以逐元素缩放另一个信号,使其从完全阻断到完全通过,同时保持可微:
- LSTM 和 GRU 单元:Sigmoid 门控决定每个时间步保留多少旧记忆、写入多少新内容,以及暴露多少状态;tanh 则负责塑造内容本身。
- SwiGLU:许多大语言模型 (LLM)的前馈层会将一个可学习投影与经 SiLU 激活的第二个投影相乘,后者是基于 sigmoid 构建的门控。
- SigLIP:这个图文模型会用各自的 sigmoid 对批次中的每个图像-描述配对进行评分,得到是或否的匹配概率,因此其损失无需在批次内进行归一化。
Sigmoid 与相关函数的区别#
- Logistic 函数:在 ML 中是 sigmoid 的同义词。在数学中,“sigmoid”也涵盖其他 S 形曲线,包括 tanh 和误差函数。
- Softmax:将整个向量归一化为总和为 1 的概率。对于两个类别,对 logits (z₁, z₂) 应用 softmax 后,第一个类别的概率为 σ(z₁ − z₂),因此两个输出的 softmax 与一个输出的 sigmoid 表示的是同一个模型。
- Tanh:经过缩放的 sigmoid,tanh(x) = 2σ(2x) − 1,输出范围为 −1 到 1、以零为中心,最大导数为 1。
- Hard sigmoid:一种分段线性近似,可避免在移动硬件上计算指数函数。MobileNetV3使用 ReLU6(x + 3) / 6;当 x < −3 时输出 0,当 x > 3 时输出 1,两者之间则为一条直线。










