损失函数大全:从分类到回归的全面解析

FreeGuideOnline 最新 2026-06-21

损失函数大全:从分类到回归的全面解析

损失函数(Loss Function)是机器学习的核心组件之一,它量化了模型预测值与真实值之间的差异。选择合适的损失函数直接影响模型的收敛速度、泛化能力以及最终性能。本教程从零开始,系统梳理分类与回归任务中最常用的损失函数,助你建立起完整知识体系。

1. 基本概念:损失、代价与目标函数的区别

在深入具体函数之前,先理清三个易混淆的术语:

  • 损失函数(Loss Function):针对单个样本,衡量模型对该样本的预测误差。记作 ( L(y, \hat{y}) )。
  • 代价函数(Cost Function):在整个训练集上所有样本损失的平均值(或求和),有时也指带正则化项的整体目标。记作 ( J(\theta) = \frac{1}{N}\sum_{i=1}^{N} L(y_i, \hat{y}_i) )。
  • 目标函数(Objective Function):优化过程中最终要最小化(或最大化)的函数,通常是代价函数加上正则化项。

本教程聚焦于最常被调用的单个样本的损失函数,并说明它们如何构成整体优化目标。

2. 回归问题损失函数

回归任务的目标是预测一个连续的数值。损失函数的核心思想是衡量预测值与真实值之间的“距离”。

2.1 均方误差(Mean Squared Error, MSE)/ L2 损失

MSE 计算预测值与真实值之差的平方,是最经典的回归损失。

公式
[ L(y, \hat{y}) = (y - \hat{y})^2 ]

特点

  • 强惩罚异常值:当误差大于 1 时,平方操作会急剧放大误差,使得模型对离群点极其敏感。
  • 梯度平滑:梯度为 ( -2(y - \hat{y}) ),线性变化,利于优化收敛。
  • 最优输出为均值:当使用 MSE 作为代价函数且无正则项时,模型的最优预测值趋近于目标的条件均值。

适用场景:要求异常值问题不严重、希望输出为均值的标准线性回归、神经网络回归。

2.2 平均绝对误差(Mean Absolute Error, MAE)/ L1 损失

MAE 计算预测值与真实值之差的绝对值。

公式
[ L(y, \hat{y}) = |y - \hat{y}| ]

特点

  • 对异常值鲁棒:误差线性增长,不会像 MSE 那样被离群点支配。
  • 梯度不连续:在零点处梯度不存在(或定义为 0 的子梯度),在优化末端可能发生震荡。
  • 最优输出为中位数:忽略噪声时,模型输出趋向于目标的条件中位数。

适用场景:数据中存在较多异常值,或不希望大误差带来不成比例的影响。

2.3 Huber 损失(Smooth L1 Loss)

Huber 损失是 MSE 与 MAE 的组合,在小误差时表现为平方损失,在大误差时表现为线性损失,通过超参数 δ 控制切换点。

公式
[ L_{\delta}(y, \hat{y}) = \begin{cases} \frac{1}{2}(y - \hat{y})^2, & \text{若 } |y - \hat{y}| \le \delta \ \delta \cdot |y - \hat{y}| - \frac{1}{2}\delta^2, & \text{否则} \end{cases} ]

特点

  • 在误差小于 δ 时连续可导且梯度稳定(类似 MSE),在大误差时梯度恒定(类似 MAE),兼具二者优点。
  • 需要调节 δ 参数,通常设为 1.0,也可基于数据分布动态调整。

适用场景:目标检测(Faster R-CNN 中的边界框回归)、对异常值有一定容忍度但仍希望保持收敛速度的回归任务。

2.4 Log-Cosh 损失

Log-Cosh 计算误差的双曲余弦的对数,是另一种平滑的鲁棒损失。

公式
[ L(y, \hat{y}) = \log(\cosh(y - \hat{y})) ]

特点

  • 对于小误差近似于 ( \frac{1}{2}(y - \hat{y})^2 ),对于大误差近似于 ( |y - \hat{y}| - \log(2) ),具有 Huber 损失类似的性质。
  • 处处二阶可导,非常适合需要 Hessian 的优化算法(如 XGBoost 中的二阶泰勒展开)。

适用场景:需要完全平滑且具有鲁棒性的回归模型。

2.5 分位数损失(Quantile Loss)

当需要预测一个区间而不仅仅是点估计时,分位数回归非常有用。

公式
对于分位数 ( \tau \in (0,1) ):
[ L_{\tau}(y, \hat{y}) = \sum_{i: y_i < \hat{y}_i} (\tau - 1) \cdot |y_i - \hat{y}i| + \sum{i: y_i \ge \hat{y}_i} \tau \cdot |y_i - \hat{y}i| ] 或简写为:
[ L
{\tau}(y, \hat{y}) = \max(\tau(y - \hat{y}), (\tau - 1)(y - \hat{y})) ]

特点

  • 非对称惩罚:低估(预测值 < 真实值)和高估的惩罚系数不同。
  • 当 ( \tau = 0.5 ) 时退化为 MAE,预测中位数;当 ( \tau = 0.9 ) 时,模型预测 90% 分位数,即真实值有 90% 概率低于预测值。

适用场景:不确定性估计、供应链需求预测(预测安全库存)、金融风险测量。

3. 分类问题损失函数

分类问题要求模型输出类别概率或分界面。损失函数基于最大化似然或最小化信息散度设计。

3.1 0-1 损失(Zero-One Loss)

最直观的损失:预测错误计 1,正确计 0。

公式
[ L(y, \hat{y}) = \mathbb{1}[y \neq \hat{y}] ]

特点:不可微分、非凸,难以直接优化。实际训练中由代理损失(如交叉熵)替代,但常作为最终评估指标。

3.2 合页损失(Hinge Loss)

用于最大间隔分类,典型的二分类集合支持向量机(SVM)的损失函数,标签 ( y \in {-1, +1} )。

公式
[ L(y, \hat{y}) = \max(0, 1 - y \cdot \hat{y}) ] 其中 ( \hat{y} ) 为模型未经过激活函数的原始输出(决策值)。

特点

  • 追求预测值 ( \hat{y} ) 与真实标签 ( y ) 的同号性且足够“确信” (>1)。
  • 一旦 ( y \cdot \hat{y} \ge 1 ),损失为零,模型不再更新,产生稀疏解。
  • 不可导点通过次梯度解决。

适用场景:线性 SVM、追求最大间隔的分类器。

3.3 交叉熵损失(Cross-Entropy Loss)/ 负对数似然(Negative Log Likelihood)

分类任务中应用最广泛的损失,度量两个概率分布之间的差异。

二分类交叉熵:标签 ( y \in {0, 1} ),预测概率 ( p = \hat{y} )。
[ L = -[y \log(p) + (1 - y) \log(1 - p)] ]

多分类交叉熵:标签为 one-hot 向量 ( \mathbf{y} ),预测分布为 ( \mathbf{p} )。
[ L = - \sum_{c=1}^{C} y_c \log(p_c) ] 其中 ( p_c ) 通常由 Softmax 函数产生。

特点

  • 与最大似然估计等价,在概率模型下理论上最优。
  • 梯度良好:二分类中梯度为 ( p - y ),多分类中每个类别的梯度为 ( p_c - y_c ),当预测完全正确时梯度消失。
  • 与 KL 散度密切相关。

适用场景:逻辑回归、神经网络、几乎所有基于概率的分类模型。

数值稳定提示:通常将 Sigmoid/Softmax 与交叉熵损失融合实现(如 softmax_cross_entropy),避免单独计算对数时出现 log(0) 的数值问题。

3.4 焦点损失(Focal Loss)

专为解决类别极度不平衡问题设计,是交叉熵损失的改进版。

公式(二分类,扩展到多分类类似):
[ L = - \alpha_t (1 - p_t)^\gamma \log(p_t) ] 其中:
[ p_t = \begin{cases} p, & y=1 \ 1-p, & y=0 \end{cases} ],
( \alpha_t ) 为类别的加权因子,( \gamma \ge 0 ) 为聚焦参数。

特点

  • 当 ( p_t ) 较大(即样本被正确分类且置信度高)时,调制因子 ( (1 - p_t)^\gamma ) 趋近于 0,降低易分类样本的损失贡献。
  • 模型更关注难分类的、被错误分类的样本。
  • 通常取 ( \gamma = 2, \alpha = 0.25 ) 在目标检测中表现优秀。

适用场景:单阶段目标检测(RetinaNet)、极度不平衡数据集(如欺诈检测、罕见病诊断)。

3.5 多标签分类:二元交叉熵与排序损失

多标签任务中,一个样本可同时属于多个类别。常用方法是为每个标签独立计算二元交叉熵(Binary Cross-Entropy with Logits),最后求和。

公式(单个样本对 C 个标签):
[ L = -\frac{1}{C}\sum_{c=1}^{C} [y_c \log(\sigma(\hat{y}_c)) + (1 - y_c)\log(1 - \sigma(\hat{y}_c))] ] 其中 ( \sigma ) 为 sigmoid 函数。

对比交叉熵与二元交叉熵:多分类交叉熵使用 Softmax,类别互斥;多标签使用独立 Sigmoid,类别不互斥。

另一种损失:Pairwise Ranking Loss 常用于学习排序,如给定正负样本对,让正样本得分高于负样本。此处不展开,但需知道其在多标签中可替代二元交叉熵。

4. 特殊场景与高级损失

4.1 Kullback-Leibler 散度损失(KL Divergence Loss)

度量两个概率分布 P 与 Q 的差异,常用于知识蒸馏、变分自编码器(VAE)。

公式
[ D_{KL}(P \parallel Q) = \sum_{x} P(x) \log \frac{P(x)}{Q(x)} ]

特点:非对称,优化时不作为距离度量,但可通过最小化负对数似然与先验分布间的 KL 散度实现正则化。

关系:交叉熵 = 熵 + KL 散度,当目标分布为 one-hot 时,KL 散度等价于交叉熵。

4.2 对比损失(Contrastive Loss)

用于学习样本之间的相似度表征,常见于孪生网络(Siamese Network)。

公式(简化版):
给定一对样本特征 ( f_a, f_b ) 和标签 ( Y )(1表示相似,0表示不相似),距离 ( D = |f_a - f_b|_2 )。
[ L = \frac{1}{2}Y D^2 + \frac{1}{2}(1-Y){\max(0, m - D)}^2 ] 其中 ( m ) 为边界超参数。

核心理念:使相似样本的距离变小,不相似样本的距离大于 m。

适用场景:人脸验证、签名验证、无监督表征学习(SimCLR 等使用的 NT-Xent 损失本质是一种对比损失)。

4.3 三重态损失(Triplet Loss)

无需成对标签,而是利用三元组:锚点(Anchor)、正样本(Positive)、负样本(Negative)。强制锚点与正样本的距离比锚点与负样本的距离小一个 margin。

公式
[ L = \max(0, d(a, p) - d(a, n) + \alpha) ] 其中 ( d ) 为距离度量(通常是欧氏距离),( \alpha ) 为 margin。

适用场景:人脸识别(FaceNet)、度量学习、图像检索。

工程难点:三元组挖掘(Triplet Mining)策略至关重要,需要选取“难”负样本以加速训练。

5. 选择损失函数的实用指南

5.1 根据任务类型速查

任务类型 首选损失函数 备注
回归(无异常值) MSE / L2 Loss 梯度稳定,输出条件均值
回归(有异常值) MAE / Huber Loss 鲁棒,Huber 提供更好的收敛性
回归(分位数需求) Quantile Loss 需指定分位数 τ
二分类 交叉熵 (Binary CE) 配合 Sigmoid 输出
多类别单标签分类 交叉熵 (Categorical CE) 配合 Softmax 输出
多标签分类 二元交叉熵 每个标签独立 Sigmoid,求和
极度不平衡分类 Focal Loss 降低易分样本权重,关注困难样本
最大间隔分类 Hinge Loss 线性 SVM 标准配置
度量学习 / 相似度 Triplet / Contrastive 需配合难例挖掘,特征归一化
知识蒸馏 KL Divergence 结合温度系数使用

5.2 实践经验

  • 损失函数的可导性与优化器:深度学习中依赖梯度下降,必须保证损失函数几乎处处可导。Huber、Smooth L1 等可解决 L1 的导数不连续问题。
  • 损失与激活函数的配套:MSE + 线性激活用于回归;交叉熵 + Sigmoid/Softmax 是分类的标准组合。错误的搭配(如 MSE + Softmax)会导致梯度消失、收敛缓慢。
  • 统计视角:MSE 假设误差符合高斯分布;MAE 假设拉普拉斯分布;交叉熵对应伯努利/多项分布。如果数据分布假定成立,相应损失函数是最大似然下的最优选择。
  • 自定义损失:实际业务中,不同误差的代价不同(如假阴性成本远高于假阳性)。可以通过修改损失函数中加权项来实现成本敏感学习,例如赋予罕见类别更高的权重。

6. 代码示例(以 Python / PyTorch 为例)

为帮助理解,下面展示常用损失函数的简单实现方式。

import torch
import torch.nn as nn
import torch.nn.functional as F

# 回归损失
mse_loss = nn.MSELoss()                     # L2
mae_loss = nn.L1Loss()                      # L1
huber_loss = nn.SmoothL1Loss(beta=1.0)      # 当 beta=1 等同于 delta=1 的 Huber

# 二分类交叉熵(需结合sigmoid)
bce_with_logits = nn.BCEWithLogitsLoss()    # 内部自动做 Sigmoid + BCE,数值稳定
# 多分类交叉熵
ce_loss = nn.CrossEntropyLoss()             # 内部自动做 LogSoftmax + NLLLoss

# 焦点损失(自定义实现简例)
def focal_loss(inputs, targets, alpha=0.25, gamma=2):
    ce = F.cross_entropy(inputs, targets, reduction='none')
    pt = torch.exp(-ce)                     # pt = e^{-ce}
    focal = alpha * (1 - pt) ** gamma * ce
    return focal.mean()

# 自定义加权二分类损失示例
class WeightedBCELoss(nn.Module):
    def __init__(self, pos_weight):
        super().__init__()
        self.pos_weight = pos_weight
    def forward(self, logits, targets):
        return F.binary_cross_entropy_with_logits(
            logits, targets, pos_weight=self.pos_weight
        )

7. 总结

损失函数是连接模型优化与业务目标的桥梁。理解每一种损失背后的统计假设与数学性质,能让你在遇到新问题时迅速做出明智选择。从 MSE 到 Focal Loss,从 Hinge 到 Triplet Loss,掌握这些“工具箱”是成为成熟机器学习工程师的必经之路。建议在下次建模时,针对你的数据分布与业务需求,尝试自定义加权、组合使用损失函数,往往会带来意想不到的提升。

进一步学习方向

  • 研究损失函数的二阶特性(如 Google 的 Bi–Tempered Log–Loss)。
  • 探索自监督学习中的 InfoNCE 损失与对比学习的结合。
  • 阅读具体模型论文(如 RetinaNet, FaceNet)中损失函数的设计细节。