你用输入法打字时,敲下拼音 hello,候选栏会弹出几个词:「hello」「哈罗」「喝了」。输入法不是随便排的——它给每个候选算了一个「可能性」,可能性高的排前面。
但模型最初算出来的不是「可能性」,而是一堆原始得分:hello 得 2.0 分,哈罗得 1.0 分,喝了得 0.1 分。这些分数有正有负、大小没上限,看着就头疼——「2.0 分」到底意味着多确信?
Softmax 要解决的就是这件事:把一组任意大小的原始得分,变成一组加起来等于 1 的概率,让你一眼看出模型倾向哪个答案。
为什么需要它:原始得分的三个毛病
神经网络输出层吐出来的一组数(叫 logits,原始得分)有三个毛病,直接拿给用户没法用:
- 没上下界:可能是 -100,也可能是 1000,你不知道「2.0」算高还是低
- 互相不可比:第一个数 2.0、第二个 1.0,差不代表第一个的可能性是第二个的两倍
- 加起来没意义:2.0 + 1.0 + 0.1 = 3.1,这个 3.1 啥也说明不了
我们需要的是一组像概率一样的数:每个都在 0 到 1 之间,且全部加起来正好等于 1(「100% 的可能性分给这几个候选」)。这就是 softmax 干的事。
公式直觉
给定一组原始得分
逐项看这个式子在做什么:
:第 个类别的原始得分(logit),由网络上一层算出来 :自然对数的底(约 2.718),指数函数 的底数 :把 套进指数函数 。指数函数有个好性质——任何实数进去都出来正数,这就把「有正有负」的得分全变成了正数 :所有 个指数化后的得分加起来,当作分母 :求和指标,遍历 1 到 (即依次取每个类别) - 整个分式:每个指数得分除以总和,得到一个占比
整个过程像把
至于为什么非用指数
图 1:指数化如何放大得分差距——同样的 2.0 与 1.0,过一遍 eˣ 后,比例从 2 : 1 被拉大到约 2.7 : 1。
计算示例:三个数字走一遍
就用开头输入法那三个候选的得分
- 指数化(分子):
- 求和(分母):
- 归一化(每个除以分母):
自检:三个概率
回头看:模型对第一个候选有约 66% 的把握,第二个约 24%,第三个约 10%——这下人能看懂了。
和 argmax、sigmoid 是什么关系
这三个函数经常被搞混,其实各管一摊:
| 函数 | 输出 | 用在哪 | 可导吗 |
|---|---|---|---|
| softmax | 一组概率(和为 1) | 多分类输出层(训练时) | 是 |
| argmax | 一个序号(最大值的位置) | 推理时挑最终答案 | 否 |
| sigmoid | 一组概率(每个独立,和不要求为 1) | 二分类 / 多标签分类 | 是 |
先解释一下表里的「可导」,它决定了谁能用来训练。训练模型靠的是「微调一点点参数,看误差怎么变」,这要求函数平滑、能算变化率(也就是「可导」);softmax 是一条平滑的曲线,满足要求,所以能参与训练。而 argmax 是「只挑最大的、其余一刀切归零」的硬操作,拐角太陡、没法算变化率,所以只在推理时用、不参与训练。
三者的关系:
softmax + argmax 是流水线:训练时用 softmax 得到概率,推理(预测)时再在概率上套 argmax,挑出概率最大的那个类别作为最终答案(argmax 直接吃原始得分也行,但概率更直观)。
softmax 是 sigmoid 的「多分类升级版」:当只有 2 个类别时,softmax 和 sigmoid 数学上等价;类别一多,sigmoid 会「各算各的」(每个类别独立给一个 0–1 的概率,互相不约束,加起来可能 >1),softmax 则强制它们分一块蛋糕(和为 1)。所以:
- 互斥的多分类(一张图只能是猫或狗或鸟)→ softmax
- 多标签分类(一张图可以同时有猫和狗)→ sigmoid,每个标签独立判断
图 2:softmax / sigmoid / argmax 一图分清——softmax 强制和为 1(互斥分类)、sigmoid 各算各的(多标签,和可超 1)、argmax 只挑最大者(其余归零)。
典型应用:多分类输出层的「最后一棒」
softmax 最经典的舞台是多分类模型的输出层。以手写数字识别(0–9 共 10 类)为例:
- 网络前面几十层把图片特征提取成一串向量
- 最后一层是全连接层,输出 10 个原始得分(logits),对应 0–9
- softmax 把这 10 个得分转成 10 个概率,每个代表「这张图是该数字的可能性」
- 训练时,这组概率再喂给一种叫交叉熵(cross-entropy)的函数算误差、更新模型(交叉熵是另一个概念,专门配合 softmax 用,本文不展开,你只要知道它负责「拿概率和真实标签比,算出误差」即可)
- 预测时,argmax 从 10 个概率里挑最大的,作为识别结果
正因为 softmax 和交叉熵总是一起用,PyTorch 干脆把两步合成了一个函数 nn.CrossEntropyLoss——用的时候模型最后一层不需要再加 softmax(这是个常见坑,下面代码里会点明)。
图 3:softmax 在多分类输出层的位置——把上一层的 logits 转成概率,训练时配合交叉熵算误差,推理时由 argmax 挑出最大概率作为答案。
完整代码
这段代码分三步走:①建一个吐 logits 的小网络 → ②训练一步(用 CrossEntropyLoss 算误差,它内部已含 softmax)→ ③推理时手动套一次 softmax 看概率、用 argmax 出预测。带着这个结构读下面的逐行注释:
import torch
import torch.nn as nn
# 一个最小的多分类网络(3 个类别)
class Classifier(nn.Module):
def __init__(self, in_dim, num_classes):
super().__init__()
# 全连接层:输出 num_classes 个 logits(原始得分)
self.fc = nn.Linear(in_dim, num_classes)
def forward(self, x):
# 关键坑:这里【故意不加 softmax】!
# 因为 nn.CrossEntropyLoss 内部已经先做 softmax 再算交叉熵,
# 如果这里再加一次 softmax,等于做了两次,模型会学坏。
return self.fc(x)
torch.manual_seed(42) # 固定随机种子,让每次跑结果一样(可复现)
model = Classifier(in_dim=4, num_classes=3)
criterion = nn.CrossEntropyLoss() # 内部自带 softmax + 交叉熵
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
# 假数据:2 个样本,每个 4 维特征
x = torch.randn(2, 4)
# 假标签:样本 0 属于类别 1,样本 1 属于类别 0(类别编号从 0 起)
y = torch.tensor([1, 0])
# —— 第②步:训练一步 ——
logits = model(x) # 前向:得到原始得分(这步故意不加 softmax)
loss = criterion(logits, y) # 关键:criterion 内部先 softmax 再算交叉熵,所以上面不能重复加
loss.backward(); optimizer.step() # 反向传播更新参数(标准训练循环,省略 zero_grad 等样板)
print(f"训练损失: {loss.item():.4f}")
# —— 推理时想看"概率",手动套一次 softmax ——
with torch.no_grad():
probs = torch.softmax(model(x), dim=1) # dim=1 表示按行归一化(每行和为 1)
print(f"每个样本属于各类的概率:\n{probs}")
print(f"每行求和(应≈1): {probs.sum(dim=1)}")
preds = probs.argmax(dim=1) # argmax 挑概率最大的类别作为预测
print(f"预测类别: {preds.tolist()}")运行后你会看到:probs 每行的三个数加起来约等于 1,preds 给出每个样本的预测类别编号——这就是 softmax + argmax 的完整工作流。
小结
一句话:softmax 把一组原始得分变成一组加起来为 1 的概率,让模型的输出从「一堆看不懂的数」变成「我有多确信每个候选」——它是多分类任务输出层的标配,和交叉熵是黄金搭档。下次你用输入法,看到候选栏把「hello」稳稳排在最前,背后多半就有 softmax 在把一堆原始得分,悄悄变成那组你看到的概率排序。
参考资料
- Softmax Regression — Dive into Deep Learning(李沐等,经典教材) https://d2l.ai/chapter_linear-classification/softmax-regression.html
- Softmax Activation Function: Everything You Need to Know — Pinecone(含 softmax/sigmoid/argmax 对比) https://www.pinecone.io/learn/softmax-activation/
- Softmax Function Definition — DeepAI Machine Learning Glossary https://deepai.org/machine-learning-glossary-and-terms/softmax-layer