Full Softmax 与候选采样原理与对比#
在深度学习中,Softmax 函数经常用于多分类任务,它能够将神经网络输出的原始分数(logits)转换为概率分布,使模型能够判断输入样本属于不同类别的可能性。
然而,当分类任务中的类别数量非常庞大时,例如需要从几十万甚至上百万个商品、网页或单词中进行选择,传统 Softmax 就会面临较大的计算开销。
为了解决这一问题,可以采用候选采样(Candidate Sampling)技术。它的核心思想是:训练模型时,不必每次都计算所有负类别的概率,只需要保留正标签,并从负类别中抽取一部分参与计算即可。这一点就类似于 word2vec 训练时所使用的负采样策略。
本文接下来要介绍的就是 Softmax 与候选采样的基本原理、区别及其在训练和推理阶段的应用。
1. 完整 Softmax(Full Softmax)#
Full Softmax 是最常见的 Softmax 计算方式,即对所有可能的类别计算概率。
假设我们正在训练一个图像分类模型,需要识别以下 5 种动物: 柯基 、金毛、猫、兔子、大象,模型接收一张图片,经过神经网络计算,得到5个原始分数(logits):
$$ z=[3.0,2.0,1.0,0.5,0.2] $$这些分数还不是概率,需要通过 Softmax 函数进行转换:
$$ P(y=i)=\frac{e^{z_i}}{\sum_{j=1}^{N}e^{z_j}} $$其中:
$z_i$:第 $i$ 个类别对应的原始分数。
$N$:类别总数。
分母:所有类别的指数分数之和。
经过 Softmax 计算后,模型得到每个类别对应的概率。例如:
| 类别 | 预测概率 |
|---|---|
| 柯基 | 56.9% |
| 金毛 | 20.9% |
| 猫 | 7.7% |
| 兔子 | 4.7% |
| 大象 | 3.5% |
可以看到,Full Softmax 的一个重要特点是:无论某个类别是否可能是正确答案,都需要计算它对应的概率。
即使模型认为图片不可能是大象,也需要计算大象对应的概率。
这种方式在类别数量较少时通常没有问题,但如果分类任务达到几十上百万的时候,那么每次训练都要计算庞大数量的类别对应的 logits,然后再进行 Softmax 归一化,此时计算成本就会非常高。
因此,在大规模分类任务中,需要考虑更加高效的计算方式。
2. 候选采样(Candidate Sampling)#
候选采样的核心思想是:训练模型时,保留所有正标签,但不必为所有负标签计算概率,只需要随机或按照特定策略抽取一部分负标签参与计算。
这里首先需要理解两个概念:
正标签(Positive Label):训练样本对应的真实类别,也就是模型需要正确识别的类别。
负标签(Negative Label):除真实类别之外的其他类别。
继续以动物分类为例。
假设当前输入图片的真实类别是柯基,那么:
正标签:柯基
负标签:金毛、猫、兔子、大象。
采用Full Softmax 时,需要计算全部五个类别。
而采用候选采样时,可以从 4 个负标签中随机抽取两个,例如金毛和猫。
于是,本次训练只需要计算 3 个类别:
柯基:正标签,必须参与计算。
金毛:采样得到的负标签,参与计算。
猫:采样得到的负标签,参与计算。
兔子和大象没有被采样,因此不参与本次计算。
这样,原本需要计算 5 个类别,现在只需要计算 3 个类别。
当类别数量达到几十万甚至上百万时,这种方式能够显著减少每次训练需要处理的类别数量。
需要注意的是,没有被采样的负标签并不意味着模型已经判断它们是错误类别,而只是它们没有参与当前这一次训练计算。
3. 候选采样如何选择负样本?#
候选采样并不意味着只能通过完全随机的方式选择负样本,因为选择与正标签越相似的样本越有利于模型训练, 因此,根据不同的任务需求,可以采用不同的采样策略。
3.1 均匀随机采样#
这是最容易理解的一种方式。
假设有 100 万个类别,去除真实类别后,还剩下 999999 个负类别。
如果每次训练只需要 1000 个样本,就可以从这些负类别中随机抽取 99 个。
此时,每个负类别被抽中的概率相同。虽然这种方式实现简单,但可能抽取到大量与当前正样本差异明显、模型很容易区分的负样本。
3.2 按类别分布采样#
由于不同类别在真实数据中的出现频率可能存在很大差异。例如,在商品推荐任务中,热门商品出现的频率通常高于冷门商品。
因此,可以根据类别的出现频率设计采样概率,让热门类别获得更高的采样概率。
这种方式能够让模型更多地接触高频类别,但也可能使模型过度关注热门类别,因此需要根据具体任务进行调整。
3.3 基于模型的采样#
还可以利用模型当前的预测结果选择负样本。
例如,模型需要识别柯基,但它很容易将金毛误判为柯基,那么,金毛就是一个比较有价值的负样本。 这类样本通常被称为困难负样本(Hard Negative)。
因此,通过优先选择模型容易混淆的负样本,可以让模型学习更加有区分性的特征。
需要注意,困难负样本挖掘与一般的随机候选采样属于相关但不同的采样策略,具体实现需要考虑额外的计算成本。
4. Full Softmax 与候选采样的区别#
两者最主要的区别在于每次训练参与计算的类别数量。
| 对比维度 | Full Softmax | 候选采样 |
|---|---|---|
| 正标签 | 全部计算 | 全部计算 |
| 负标签 | 全部计算 | 只计算部分 |
| 计算范围 | 所有类别 | 正标签 + 采样负标签 |
| 计算成本 | 类别数量较大时较高 | 通常较低 |
| 适用场景 | 类别数量较少 | 类别数量非常大 |
从计算目标来看,Full Softmax 试图在全部类别中建立概率分布,而候选采样则通过缩小每次训练所涉及的类别集合,降低计算开销。
5. 候选采样只用于训练阶段吗?#
这是一个容易产生疑问的问题。
一般来说,候选采样主要用于降低训练阶段的计算开销。但在推理阶段,是否需要计算全部类别,取决于具体任务的推理方式。
5.1 训练阶段#
使用Full Softmax 时,每次训练都需要计算所有类别的 logits,并通过 Softmax 得到完整的概率分布。
使用候选采样时,则只需要计算全部正标签以及部分采样负标签。
例如,有 100 万个类别:
Full Softmax:每次训练计算 100 万个类别。
候选采样:每次训练只计算正标签和采样得到的 999 个负类别。
5.2 推理阶段#
假设模型需要从全部 100 万个类别中找到概率最高的类别。
在这种情况下,通常仍然需要计算全部类别的 logits。
不过,如果预测任务只是为了找到概率最高的类别,就不一定需要执行 Softmax 归一化。
因为 Softmax 不会改变 logits 的大小顺序:
$$ \arg\max_i P(y=i)=\arg\max_i z_i $$因此,直接比较 logits 就可以找到概率最高的类别,这也是为什么我们在实现分类模型代码的时候前向传播里不会有 softmax 的原因(直接放到了优化器里)。
所以,在模型推理阶段中,Full Softmax 和候选采样都不需要进行 Softmax 操作。