Softmax 把一组有限实数得分归一化成和为 1 的分布。它适合表示互斥候选项的相对权重,但“模型给出 82%”并不自动意味着现实中有 82% 的正确率。
公式要说明沿哪个维度
对于 n 个 logits z,定义:
p_i = exp(z_i) / Σ_j exp(z_j)
理论上各项为正、和为 1,并保持得分的大小顺序;浮点实现中很小的项可能下溢成 0。负数得分也能处理,不需要先把输入变成正数。
张量上必须指定归一化维度。例如形状为 [batch, classes],沿 classes 计算时,每个样本得到自己的类别分布,而不是把所有样本一起归一化。PyTorch Softmax 的 dim 契约
三个得分的实际结果
设猫、狗、鸟的 logits 为 [3,1,0.5]:
exp(3) ≈ 20.085537
exp(1) ≈ 2.718282
exp(0.5) ≈ 1.648721
Softmax ≈ [0.821409, 0.111166, 0.067425]
百分比 ≈ [82.14%, 11.12%, 6.74%]
因此不是 [85%,12%,3%]。归一化不是把原始得分直接除以总得分,指数操作会改变相对比例。
减去最大值,避免大正数指数溢出
所有项统一减去最大值,分子分母同除 exp(max),理论结果不变:
function softmax(scores) {
if (!Array.isArray(scores) || scores.length === 0 ||
!scores.every(Number.isFinite)) {
throw new TypeError("scores 必须是非空有限数值数组");
}
const maximum = scores.reduce((a, b) => Math.max(a, b), -Infinity);
const weights = scores.map(value => Math.exp(value - maximum));
const total = weights.reduce((a, b) => a + b, 0);
return weights.map(value => value / total);
}
console.log(softmax([3, 1, 0.5]));
console.log(softmax([1003, 1001, 1000.5]));
两组有限输入相差同一个常数,得到相同分布。这个教学实现拒绝空数组、NaN 和无穷值,不包含张量、掩码或自动求导;不能直接代替训练框架中的稳定算子。
Softmax 不等于 argmax,也不保证校准
只要最大项下标,直接 argmax 即可;Softmax 不改变最大项。需要保留候选分布或采样时,才需要相对权重。
加常数不改分布,但乘常数会改变尖锐程度。用 z/T 计算且 T>0 时,较大的温度使分布更平缓,较小的温度使分布更集中;这不等于凭温度让回答更可靠。
训练时还要服从损失函数的输入契约:接收 logits 的损失不要预先再做 Softmax;NLLLoss 则需要对数概率,不能直接喂普通概率。数值稳定性、训练目标与现实概率校准是不同问题。