Personal Knowledge Base

A long-term research and learning notebook for posts, notes, papers, projects, and research directions.

Skip to content
← Back to blog
Deep Learningpublished

常用损失函数:从误差度量到任务目标

系统梳理机器学习与深度学习中常见的损失函数,理解它们的数学形式、梯度特性、适用场景,以及如何根据任务选择和组合损失。

14 min read

损失函数(loss function)把模型的预测结果映射成一个标量,用来衡量预测与目标之间的差异。训练过程通常是在最小化经验风险:

L(θ)=1Ni=1N(fθ(xi),yi)\mathcal{L}(\theta)=\frac{1}{N}\sum_{i=1}^{N}\ell\big(f_\theta(x_i),y_i\big)

其中,fθf_\theta 是参数为 θ\theta 的模型,xix_i 是输入,yiy_i 是标签,\ell 是单个样本的损失。损失函数并不只是一个“打分器”:它实际上定义了模型要重视什么、忽略什么,以及参数更新时的方向和幅度。

先看三个选择标准

选择损失函数时,可以先问三个问题:

  1. 标签是什么类型? 连续值、类别、概率分布,还是集合或序列?
  2. 错误的代价是否对称? 预测偏大和偏小是否同样严重?少数类漏检是否比误报更昂贵?
  3. 数据中是否有异常值或类别不平衡? 它们会决定损失是否需要更加鲁棒或重新加权。

还要区分训练目标与评估指标。例如,分类任务常用交叉熵训练,却用 accuracy、F1 或 AUROC 评估;检测任务常把分类损失、边界框回归损失和 IoU 损失组合起来。一个好的损失函数,应该让优化目标与真正关心的结果尽量一致。

回归损失

回归任务的标签通常是连续值。设误差为 e=y^ye=\hat{y}-y

MSE:均方误差

LMSE=1Ni=1N(y^iyi)2\mathcal{L}_{\mathrm{MSE}}=\frac{1}{N}\sum_{i=1}^{N}(\hat{y}_i-y_i)^2

MSE 对误差进行平方,因此大误差会被快速放大。它在误差服从高斯分布、且大误差确实应该受到更重惩罚时很自然;最小化 MSE 也对应于拟合条件均值。

优点是连续、光滑、容易优化。缺点是对异常值敏感:一个极大的误差可能主导整个 batch 的梯度。如果标签的长尾很明显,可以考虑对目标做标准化,或改用更鲁棒的损失。

MAE:平均绝对误差

LMAE=1Ni=1Ny^iyi\mathcal{L}_{\mathrm{MAE}}=\frac{1}{N}\sum_{i=1}^{N}\left|\hat{y}_i-y_i\right|

MAE 对误差进行线性惩罚,相比 MSE 不容易被异常值牵着走。它更接近拟合条件中位数,因此当数据中存在离群点、或者大误差不应该被过度放大时很有用。

MAE 在 e=0e=0 处不可导。实际实现会使用次梯度,通常不会造成问题,但它的梯度幅度基本不随误差变大而增加,可能使训练收敛速度不如 MSE。

Huber Loss:MSE 与 MAE 的折中

Lδ(e)={12e2,eδδ(e12δ),e>δ\mathcal{L}_{\delta}(e)= \begin{cases} \frac{1}{2}e^2, & |e|\leq\delta \\ \delta\left(|e|-\frac{1}{2}\delta\right), & |e|>\delta \end{cases}

Huber Loss 在小误差区域像 MSE,在大误差区域像 MAE。参数 δ\delta 决定两种行为的切换位置:δ\delta 越大,损失越接近 MSE;δ\delta 越小,损失越接近 MAE。

它经常用于目标检测中的边界框回归,因为模型早期可能产生较大的定位误差,而这些误差不应让梯度完全失控。Smooth L1 Loss 可以看作 Huber Loss 的一个常见实现形式或缩放版本。

对数双曲余弦损失

Llogcosh(e)=log(cosh(e))\mathcal{L}_{\mathrm{logcosh}}(e)=\log\big(\cosh(e)\big)

在小误差附近,log(cosh(e))e2/2\log(\cosh(e))\approx e^2/2;在大误差区域,它近似 elog2|e|-\log 2。因此它同时具有 MSE 的平滑性和 MAE 的鲁棒性。它的梯度是 tanh(e)\tanh(e),天然被限制在 (1,1)(-1,1)

分类损失

分类损失通常来自概率建模:模型输出一个概率分布,损失衡量真实标签在该分布下的负对数似然。

Binary Cross-Entropy:二分类交叉熵

对标签 y{0,1}y\in\{0,1\} 和预测概率 p(0,1)p\in(0,1)

LBCE=[ylogp+(1y)log(1p)]\mathcal{L}_{\mathrm{BCE}}=-\left[y\log p+(1-y)\log(1-p)\right]

BCE 会强烈惩罚“自信但错误”的预测。例如真实标签为 1,而模型给出接近 0 的概率时,损失会很大。多标签分类中,每个类别都可以独立使用 BCE。

工程上更推荐直接使用 logits 版本的实现,例如 PyTorch 中的 BCEWithLogitsLoss,让 sigmoid 与数值稳定的 log-sum-exp 计算在同一个算子中完成。不要先手动 sigmoid,再把结果传给 logits 版本。

Multi-Class Cross-Entropy:多分类交叉熵

对于 KK 个互斥类别,模型输出 logits z1,,zKz_1,\ldots,z_K,softmax 概率为:

pk=exp(zk)j=1Kexp(zj)p_k=\frac{\exp(z_k)}{\sum_{j=1}^{K}\exp(z_j)}

若真实类别为 yy,交叉熵为:

LCE=logpy\mathcal{L}_{\mathrm{CE}}=-\log p_y

它等价于 softmax 输出分布与 one-hot 标签分布之间的交叉熵,也是多分类中最常见的默认选择。实现时通常直接传入 logits 和整数类别索引,而不是手动计算 softmax。

Label Smoothing:标签平滑

硬标签会把真实类别的目标概率设为 1,其余类别设为 0。标签平滑把目标改为:

y~k=(1ε)yk+εK\tilde{y}_k=(1-\varepsilon)y_k+\frac{\varepsilon}{K}

它能减弱模型过度自信,通常对泛化和校准有帮助,尤其适用于训练标签存在轻微噪声的场景。但平滑过强会降低类别之间的学习信号;ε\varepsilon 应作为正则化超参数,而不是越大越好。

Focal Loss:聚焦损失

在二分类中,令 ptp_t 表示真实类别对应的预测概率:

Lfocal=αt(1pt)γlog(pt)\mathcal{L}_{\mathrm{focal}}=-\alpha_t(1-p_t)^\gamma\log(p_t)

其中 γ0\gamma\geq 0 控制对容易样本的降权程度,αt\alpha_t 用来平衡类别权重。当样本已经被正确分类、且 ptp_t 很大时,(1pt)γ(1-p_t)^\gamma 会压低它的贡献,让训练更集中于难样本和少数类。

Focal Loss 常用于目标检测和严重类别不平衡的分类任务。如果数据并不失衡,或者难样本本身含有大量噪声,过度聚焦可能让模型过分追逐异常样本。

Hinge Loss:合页损失

二分类 SVM 常使用:

Lhinge=max(0,1yf(x)),y{1,+1}\mathcal{L}_{\mathrm{hinge}}=\max(0,1-yf(x)),\qquad y\in\{-1,+1\}

它不仅要求分类正确,还要求样本位于分类间隔之外。与交叉熵相比,Hinge Loss 更直接地优化间隔;但它在间隔已经满足后不再提供梯度,因此在现代深度分类网络中通常不如交叉熵常见。

分割与重叠区域损失

像素级分割常面临前景稀疏、类别不平衡和边界质量难以用逐像素损失表达的问题。这时,基于区域重叠的损失很有价值。

Dice Loss

Dice 系数为:

Dice(P,G)=2ipigi+ϵipi+igi+ϵ\mathrm{Dice}(P,G)=\frac{2\sum_i p_i g_i+\epsilon}{\sum_i p_i+\sum_i g_i+\epsilon}

对应的 Dice Loss 通常写成:

LDice=1Dice(P,G)\mathcal{L}_{\mathrm{Dice}}=1-\mathrm{Dice}(P,G)

它直接衡量预测区域与真实区域的重叠程度,对前景占比很小的任务比较友好,例如医学图像分割。实践中常把 Dice Loss 与 BCE 或 CE 相加:前者关注区域重叠,后者提供更稳定的逐像素概率监督。

IoU / Jaccard Loss

IoU(P,G)=ipigi+ϵipi+igiipigi+ϵ\mathrm{IoU}(P,G)=\frac{\sum_i p_i g_i+\epsilon} {\sum_i p_i+\sum_i g_i-\sum_i p_i g_i+\epsilon}

IoU Loss 可以写为 1IoU(P,G)1-\mathrm{IoU}(P,G)。它与最终的交并比指标更一致,但梯度行为有时不如交叉熵稳定。和 Dice 一样,需要在分母中加入 ϵ\epsilon,以避免前景为空时出现数值问题。

度量学习损失

度量学习不一定直接预测类别,而是学习一个嵌入空间:相似样本靠近,不相似样本分离。

Contrastive Loss:对比损失

dd 是两个样本嵌入之间的距离,y=1y=1 表示相似,y=0y=0 表示不相似:

Lcontrastive=yd2+(1y)max(0,md)2\mathcal{L}_{\mathrm{contrastive}} =y\,d^2+(1-y)\max(0,m-d)^2

相似样本会被拉近,不相似样本只有在距离小于 margin mm 时才会被推远。margin 太小会导致负样本分离不足,太大则可能让训练持续受到大量无关负样本影响。

Triplet Loss:三元组损失

给定 anchor、positive 和 negative,常见形式为:

Ltriplet=max(0,d(a,p)d(a,n)+m)\mathcal{L}_{\mathrm{triplet}} =\max\left(0,d(a,p)-d(a,n)+m\right)

它要求 negative 至少比 positive 远一个 margin。Triplet Loss 的效果高度依赖样本挖掘策略;随机采样的三元组往往太容易,产生的梯度接近于零,因此 batch 内 hard negative 或 semi-hard negative mining 通常很重要。

概率模型与生成模型中的损失

KL Divergence:KL 散度

对两个离散分布 PPQQ

DKL(PQ)=xP(x)logP(x)Q(x)D_{\mathrm{KL}}(P\|Q)=\sum_x P(x)\log\frac{P(x)}{Q(x)}

KL 散度衡量用 QQ 近似 PP 时损失了多少信息。它不是对称距离,DKL(PQ)D_{\mathrm{KL}}(P\|Q)DKL(QP)D_{\mathrm{KL}}(Q\|P) 一般不同。

在变分自编码器(VAE)中,KL 项通常用于让近似后验接近先验:

LVAE=Lreconstruction+βDKL(q(zx)p(z))\mathcal{L}_{\mathrm{VAE}} =\mathcal{L}_{\mathrm{reconstruction}} +\beta D_{\mathrm{KL}}\big(q(z\mid x)\|p(z)\big)

β\beta 控制重构质量与潜变量规整程度之间的平衡。KL 权重过大可能导致 posterior collapse,训练时常需要 warm-up 或调小权重。

Negative Log-Likelihood:负对数似然

LNLL=logpθ(yx)\mathcal{L}_{\mathrm{NLL}}=-\log p_\theta(y\mid x)

NLL 是一个非常通用的概率训练目标。回归中的 MSE、分类中的交叉熵,都可以从特定概率分布的负对数似然推导出来:高斯假设导出平方误差,伯努利或 categorical 分布导出交叉熵。

这个视角很有用,因为它提醒我们:损失函数隐含了对标签噪声和不确定性的假设。若预测目标本身具有多峰、不确定或异方差,仅优化一个点估计的 MSE 可能会把多个合理答案平均成一个并不存在的答案。

损失函数如何组合

复杂任务通常需要多项损失共同约束模型:

Ltotal=λ1L1+λ2L2++λnLn\mathcal{L}_{\mathrm{total}} =\lambda_1\mathcal{L}_1+\lambda_2\mathcal{L}_2+\cdots+\lambda_n\mathcal{L}_n

常见的组合方式包括:

  • 分割: Cross-Entropy + Dice Loss,兼顾像素级监督和区域重叠。
  • 目标检测: 分类损失 + Huber/Smooth L1 回归损失 + IoU 类损失。
  • VAE: 重构损失 + KL 散度。
  • 表征学习: 分类交叉熵 + 对比学习损失,兼顾任务性能和嵌入结构。

组合损失时,首先要检查各项的数值尺度和梯度尺度。某一项数值更大,并不一定意味着它更重要;真正影响训练的是它在反向传播中提供的梯度。可以记录每个损失项及其梯度范数,再决定是否需要归一化、重新加权或使用动态权重。

一个实用选择表

任务默认起点需要特别关注
连续值回归MSE异常值、目标尺度
含离群点的回归Huber 或 MAE收敛速度与鲁棒性的平衡
二分类BCE with logits类别不平衡、概率校准
多分类Cross-Entropy标签噪声、过度自信
多标签分类对每个类别使用 BCE正负样本比例
像素级分割CE + Dice空前景、边界质量
嵌入检索Contrastive 或 Triplet负样本挖掘、margin
VAEReconstruction + KLKL 权重、posterior collapse

训练前的最后检查

  1. 先确认输出与损失匹配。 例如,CrossEntropyLoss 接收 logits,不需要提前 softmax;BCEWithLogitsLoss 接收未经过 sigmoid 的 logits。
  2. 检查标签编码。 类别索引、one-hot、概率标签和 {-1, +1} 标签对应的损失不同。
  3. 处理 reduction。 meansum 和按样本保留损失会改变梯度尺度,尤其要留意不同 batch size 下的行为。
  4. 观察难例是否真的在起作用。 使用 Focal、Triplet 或 hard mining 后,应确认模型是在学习有意义的难例,而不是追逐错误标签。
  5. 让损失服务于指标。 如果业务真正关心召回率、IoU 或排序质量,就不要只因为某个损失函数常见而机械使用它。

损失函数是任务目标的可微近似。先明确什么样的错误最值得惩罚,再选择能够稳定表达这种偏好的函数。

Related Posts