← 返回笔记列表
深度学习 第 16 / 49 篇

深度学习:神经网络的多分类 — Softmax 与交叉熵损失

查看“深度学习”专题目录(16/49)
本文目录 15 个小节

1. 改造输出层

逻辑回归也可以通过 multinomial/softmax 形式在一个模型中完成多分类,不必总是使用一对多。神经网络可以直接在一个模型内完成。

做法

  • 需要分几类,输出层就设几个神经元
  • 每个神经元输出一个 [0,1] 的值,代表样本属于该类别的概率

例如三分类: img

输入层 → 隐藏层 → 输出层(3个神经元)
                        ↓
                   [0.05, 0.90, 0.05]  → 属于第 2 类

Logits

输出层经过线性变换、还没有经过激活函数的值,称为 logits。logits 经过激活函数后才变成最终的概率输出。


2. Softmax 激活函数

2.1 一个朴素想法的问题

想让输出变成概率,最直接的想法:每个神经元的 logits 除以所有 logits 之和。

oi=ziz1+z2+z3o_i = \frac{z_i}{z_1 + z_2 + z_3}

两个问题:

问题原因
概率可能为负logits 有正有负,直接除,负值得到负概率
不同类别差异是线性的[2, 2, 5] 归一化 → [0.22, 0.22, 0.56],差异不够大,训练慢

2.2 Softmax 解法

两步:先取指数,再归一化。

三分类示例(3 个 logits z1,z2,z3z_1, z_2, z_3,输出概率 o1,o2,o3o_1, o_2, o_3):

o1=ez1ez1+ez2+ez3o2=ez2ez1+ez2+ez3o3=ez3ez1+ez2+ez3o_1 = \frac{e^{z_1}}{e^{z_1} + e^{z_2} + e^{z_3}} \qquad o_2 = \frac{e^{z_2}}{e^{z_1} + e^{z_2} + e^{z_3}} \qquad o_3 = \frac{e^{z_3}}{e^{z_1} + e^{z_2} + e^{z_3}}

2.3 通用公式

nn 个类别,第 ii 个类别的概率:

oi=ezi∑j=1nezjo_i = \frac{e^{z_i}}{\sum_{j=1}^{n} e^{z_j}}

img

2.4 Softmax 的两个优势

优势一:解决负值问题

exe^x 永远是正数 → 所有分子分母为正 → 输出概率永远在 (0, 1) 之间且为正。

优势二:放大差异,加速训练

exe^x 的指数增长,将微小的 logits 差异非线性放大:

方法[2, 2, 5] 的结果
直接归一化[0.22, 0.22, 0.56] — 差异平缓
Softmax[0.045, 0.045, 0.909] — 差异明显

类别 3 的概率从 0.56 被拉到了 0.91,模型”更自信”了。这给出一个有效的可微概率映射,不保证训练更快;过于尖锐的 softmax 也可能产生饱和。实际计算应减去最大 logit,或直接使用框架的稳定实现。


3. 多分类交叉熵损失

3.1 从二分类 BCE 到多分类 CE

二分类 BCE:

BCE=−[ylog⁡y^+(1−y)log⁡(1−y^)]\text{BCE} = -[y\log\hat{y} + (1-y)\log(1-\hat{y})]

多分类的交叉熵是它的自然推广。

3.2 设定

  • 类别数 = CC
  • 真实标签用独热(one-hot)向量:y=(y1,y2,…,yC)y = (y_1, y_2, \dots, y_C),只有真实类别对应位置为 1,其余为 0
  • 预测概率分布:p=(p1,p2,…,pC)p = (p_1, p_2, \dots, p_C),是 Softmax 输出,满足 ∑pi=1\sum p_i = 1

3.3 公式

单个样本:

loss=−∑i=1Cyilog⁡(pi)\text{loss} = -\sum_{i=1}^{C} y_i \log(p_i)

由于 one-hot 中只有一个是 1,上式展开后只剩一项:

loss=−log⁡(py)\text{loss} = -\log(p_y)

其中 pyp_y 是模型对真实类别给出的预测概率。

  • py=1p_y = 1 → loss = 0(完全正确)
  • py→0p_y \to 0 → loss →+∞\to +\infty(完全错误,重罚)

3.4 批量样本

batch size = NN:

loss=−1N∑n=1N∑i=1Cyinlog⁡(pin)\text{loss} = -\frac{1}{N} \sum_{n=1}^{N} \sum_{i=1}^{C} y_i^n \log(p_i^n)

4. 多分类 vs 二分类的输出层设计

输出神经元数激活函数损失函数
二分类1 个SigmoidBCELoss
二分类(备选)2 个训练直接传 logitsCrossEntropyLoss
多分类C 个训练直接传 logitsCrossEntropyLoss

二分类也可以用 2 个输出神经元 + Softmax。但实践中更常用 1 个神经元 + Sigmoid,参数更少,效率更高。


5. 总结

多分类神经网络的完整数据流:

输入 X
  ↓
隐藏层(线性变换 + ReLU)
  ↓
输出层(线性变换)→ logits(未激活的原始值)
  ↓
Softmax → 概率分布(和 = 1,每项在 (0,1))
  ↓
训练:CrossEntropyLoss 直接接收 logits,常用 long 类型类别索引
推理:对 logits 做 Softmax 得到概率
  ↓
梯度反向传播 → 更新所有层参数

关键理解:
  Softmax 的指数运算 = 解决正负问题 + 放大类间差异
  交叉熵 = 只看真实类别对应的预测概率,越接近 1 越好

对于单 logit 二分类,通常优先使用 BCEWithLogitsLoss,训练前不再手动 sigmoid。多标签问题与互斥多分类不同,通常是每类独立 logit 配合二元交叉熵。

继续学习本专题