NLLoss 和 CrossEntropyLoss 的区别
最近在学习损失函数的时候,经常遇到 NLLoss 和 CrossEntropyLoss 这两个概念.它们都在分类问题中广泛使用,但有时我们会混用这两者,导致不清楚它们的具体区别.
什么是 NLLoss?
NLLoss(Negative Log Likelihood Loss)即负对数似然损失.它的核心思想是:如果模型输出每个类别的概率分布,我们希望最大化真实类别的概率,也就是最小化它的负对数.
公式如下:
其中:
- ( y_i ) 是真实标签的 one-hot 编码,只有真实类别的位置是 1,其他位置是 0.
- ( p_i ) 是模型输出的类别概率.
简而言之,NLLoss 是对预测概率进行对数处理,然后计算损失.因此,NLLoss 需要模型的输出是经过 softmax 归一化后的概率分布.
下图展示了 CrossEntropyLoss 的完整工作流程,包括 CNN 输出 logits,经过 Softmax 和损失计算的过程:
特点
- 适合多分类问题.
- 需要模型输出已经经过 softmax 处理的概率分布.
- 对真实类别的预测概率越高,损失越小.
什么是 CrossEntropyLoss?
CrossEntropyLoss(交叉熵损失)可以看作是 NLLoss 和 softmax 的结合.模型输出 logits(未归一化的分数),CrossEntropyLoss 会先对 logits 进行 softmax 归一化,再计算 NLLoss.
公式可以分为两步:
- Softmax:
- Negative Log Likelihood:
其中 ( z_i ) 是 logits.
特点
- 同样适合多分类问题.
- 接收未经过 softmax 的 logits,内部会自动完成 softmax 和损失计算.
- 更加方便,因为不需要手动计算 softmax,从而减少了数值不稳定的风险(例如接近 0 或极大的值).
NLLoss 和 CrossEntropyLoss 的区别
输入要求不同
- NLLoss 需要模型输出的概率分布(即经过 softmax 处理后的值).
- CrossEntropyLoss 接收 logits(未归一化的分数),内部会自动进行 softmax 处理.
数值稳定性
- NLLoss 如果输入的概率分布中有接近 0 的值,计算对数时会导致数值不稳定(-inf).
- CrossEntropyLoss 将 softmax 和 log 的计算合并,避免了对小概率值直接取对数的问题,因此更加稳定.
方便性
- 使用 CrossEntropyLoss 时,只需直接输入 logits,省去手动计算 softmax 的步骤.
- 使用 NLLoss 时,需要确保输入已经是经过 softmax 归一化的概率,这可能需要额外的处理步骤.
应用场景
- 如果模型的输出已经通过 softmax 归一化,可以使用 NLLoss.
- 如果模型输出的是 logits(这是更常见的情况),则使用 CrossEntropyLoss 更为方便.
两者的联系
可以说,CrossEntropyLoss 是 NLLoss 的”进阶版”或者”封装版”.它的功能包括了 NLLoss,只是额外进行了 softmax 归一化.因此,它们的目标是一致的,都是为了最大化真实类别的概率.
- 本质上,二者优化的目标相同.
- CrossEntropyLoss 提供了一个更高效且实用的选择,特别是在实际工程中.
发展方向
尽管 NLLoss 和 CrossEntropyLoss 已经非常经典,但在某些场景下,也有一些改进版的损失函数:
- Focal Loss:用来处理类别不平衡问题,降低对容易分类样本的关注,增加对难分类样本的关注.
- Label Smoothing:在计算损失时,对真实标签的 one-hot 编码进行平滑,减小模型的过拟合风险.
- Custom Loss:根据具体任务需求,可以设计自定义的损失函数,比如加权交叉熵.
这些都是针对分类任务的进一步优化,但它们的核心思想依然与 NLLoss 和 CrossEntropyLoss 密切相关.
下图展示了损失函数优化过程中,损失值随训练轮次下降的情况:
总结
NLLoss 和 CrossEntropyLoss 的核心目标是一致的,都是为了最大化真实类别的概率.NLLoss 是基础形式,但需要手动处理 softmax;而 CrossEntropyLoss 更高效且稳定,适合大多数实际场景.在分类问题中,理解它们的区别和联系有助于我们在不同情况下选择合适的损失函数.