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 则需要对数概率,不能直接喂普通概率。数值稳定性、训练目标与现实概率校准是不同问题。