【huber损失】 — 稳健回归中的强大工具

在机器学习和统计回归任务中,我们总是需要一个衡量模型预测误差的指标,这就是损失函数(Loss Function)。损失函数指导着模型的学习方向,告诉模型何时做对了,何时做错了,以及错的程度有多大。常见的损失函数包括均方误差(Mean Squared Error, MSE或L2损失)和平均绝对误差(Mean Absolute Error, MAE或L1损失)。然而,这两种损失函数在面对数据中的“异常值”(Outliers)时,各有其局限性。

Huber损失正是一种旨在结合MSE和MAE优点,以更稳健地处理异常值的损失函数。它在误差较小时表现类似MSE,在误差较大时表现类似MAE,从而在保证模型收敛性的同时,降低异常值对模型训练的剧烈影响。

【huber损失】是什么? – 定义与构成

Huber损失,通常表示为 Lδ(e),其中 ‘e’ 是预测误差(即真实值与预测值之差),而 ‘δ’ (delta) 是一个关键的阈值参数,它定义了“误差较小”和“误差较大”的界限。Huber损失是一个分段函数,其定义如下:

Lδ(e) =

   { 0.5 * e²               如果 |e| ≤ δ

   { δ * |e| – 0.5 * δ²   如果 |e| > δ

这个定义可以帮助我们回答以下问题:

  • Huber损失的构成是什么? 它由两部分组成:
    • 当绝对误差 |e| 小于或等于阈值 δ 时,损失函数采用平方项 (0.5 * e²),这与MSE(L2损失)的形式相同。
    • 当绝对误差 |e| 大于阈值 δ 时,损失函数采用线性项 (δ * |e| – 0.5 * δ²),这与MAE(L1损失)的形式类似,但进行了一些调整以确保函数在 δ 处连续且可导。
  • 阈值 δ 在 Huber 损失中扮演什么角色? δ 是一个超参数,它决定了 Huber 损失何时从平方行为切换到线性行为。
    • 如果 δ 非常大,使得对于大多数或所有误差 |e| 都有 |e| ≤ δ,那么 Huber 损失基本上退化为MSE(L2损失)。
    • 如果 δ 非常小,使得对于大多数或所有误差 |e| 都有 |e| > δ,那么 Huber 损失会接近于MAE(L1损失),除了在零点附近有一个很小的平滑区域。
    • 选择合适的 δ 是使用 Huber 损失的关键,它平衡了对小误差的二次惩罚和对大误差的线性惩罚。

【huber损失】为什么使用? – 优势与比较

那么,相比于常见的MSE和MAE,为什么我们要选择使用Huber损失呢?这主要在于它在处理异常值时的稳健性以及在误差接近零时的平滑性。

相比于MSE (均方误差):

  • MSE 对异常值高度敏感: MSE 计算误差的平方。这意味着即使是一个很小的误差平方后也会放大,而一个很大的误差平方后会被极大地放大。当数据中存在异常值时(即某些样本的误差 e 很大),e² 会变得非常巨大,这会使得模型在训练时过度关注这些异常值,试图去拟合它们,从而可能牺牲对大多数正常样本的拟合精度。损失函数对误差的平方增长,意味着梯度对误差的增长也是线性的,异常值会产生巨大的梯度,导致模型参数被异常值“拉跑”。
  • Huber 损失对异常值更稳健: 当误差 |e| 大于 δ 时,Huber 损失采用线性惩罚 δ * |e|。这意味着即使误差非常大,损失也只是线性增长,而不是二次增长。因此,异常值对总损失的贡献以及对模型参数更新的梯度影响会被“抑制”,不会像MSE那样不成比例地放大。这种线性惩罚使得模型不容易被少数几个异常值主导。

相比于MAE (平均绝对误差):

  • MAE 在零点不可导: MAE 计算误差的绝对值 |e|。当误差 e 等于零时,|e| 的导数是未定义的(不光滑)。虽然在实践中可以通过次梯度来处理,但这会给优化过程带来一些不便,尤其是在使用基于梯度的优化方法时(如梯度下降)。当误差接近零时,梯度是固定的 ±1,这可能导致模型在最优值附近震荡,收敛速度变慢。
  • Huber 损失在零点附近光滑可导: Huber 损失在 |e| ≤ δ 的区域使用二次函数 0.5 * e²。二次函数在 e=0 处是光滑且可导的,其导数是 e。这使得Huber损失函数在零点附近是连续可导的,优化过程更加顺畅,有助于模型更快地收敛到最优解。在误差很小的时候,梯度是 e,误差越小梯度也越小,这有助于模型在接近最优解时进行更精细的调整。

综上,Huber损失通过结合两者的优点,实现了在异常值存在时比MSE更稳健,在误差接近零时比MAE更易于优化和收敛。

【huber损失】如何计算? – 公式与梯度

计算Huber损失对于给定的一组误差向量 E = [e₁, e₂, …, en](其中 ei 是第 i 个样本的误差)和选定的阈值 δ,通常计算的是所有样本损失的平均值或总和。对于单个样本误差 ei,其Huber损失 Lδ(ei) 就是根据上面的分段公式计算。

在模型训练中使用基于梯度的优化方法(如梯度下降、Adam等)时,我们需要计算Huber损失相对于模型参数的梯度。根据链式法则,这需要计算损失函数相对于误差 e 的梯度 ∂Lδ/∂e,然后再乘以误差 e 相对于模型参数的梯度。

Huber损失对误差 e 的梯度 ∂Lδ/∂e 如下:

∂Lδ/∂e =

   { e       如果 |e| ≤ δ

   { δ * sign(e)   如果 |e| > δ

其中 sign(e) 是 e 的符号函数:如果 e > 0 则 sign(e)=1,如果 e < 0 则 sign(e)=-1,如果 e = 0 则 sign(e)=0。

可以看到:

  • 当误差 |e| ≤ δ 时,梯度是 e。这意味着梯度随着误差线性变化,误差越小,梯度越小,有助于精确收敛。
  • 当误差 |e| > δ 时,梯度是固定的 ±δ。这意味着对于较大的误差(异常值),梯度的大小被限制在 δ,不再随误差大小线性或二次增长。这有效地“限幅”了异常值引起的梯度,防止模型参数被异常值大幅拉动。

正是这个“限幅”梯度的特性,使得Huber损失在优化过程中对异常值表现出强大的鲁棒性。

【huber损失】在哪里使用? – 应用场景

Huber损失主要应用于回归问题,尤其是在数据可能包含异常值的情况下。具体应用场景包括但不限于:

  • 鲁棒回归模型: Huber损失是构建鲁棒回归模型的核心组件之一,用于代替传统的最小二乘法损失(MSE)。
  • 机器学习模型的损失函数: 在使用梯度下降等方法训练各种回归模型时,如线性回归、支持向量回归(SVR)、神经网络、梯度提升树(如XGBoost、LightGBM)等,可以将默认的MSE或MAE替换为Huber损失,以提高模型对异常值的抵抗能力。
  • 数据预处理不完善的场景: 如果数据收集或处理过程中难以完全清除或识别异常值,使用Huber损失可以在一定程度上减轻这些异常值对模型训练的影响。
  • 金融建模: 金融数据常常包含尖峰和异常波动,Huber损失可以帮助构建更稳健的金融预测模型。
  • 计算机视觉与图像处理: 在一些涉及回归的任务,例如目标检测中的边界框回归,Huber损失(或其变体,如Smooth L1损失)被广泛使用,因为边界框标注可能存在一些误差或异常值。

【huber损失】参数 δ 如何选择? – 实践与考量

选择合适的阈值 δ 是使用Huber损失的关键。δ 决定了函数在哪个误差范围 (|e| ≤ δ) 表现为二次函数,在哪个范围 (|e| > δ) 表现为线性函数。δ 的选择没有一个通用的最优值,它通常是一个需要通过实验和验证来确定的超参数。

选择 δ 的考量:

  • δ 的含义: δ 可以理解为区分“正常误差”和“较大误差/异常值”的阈值。我们期望在正常误差范围内使用对误差变化敏感的二次惩罚(类似MSE),而在误差超出这个范围时采用更温和的线性惩罚(类似MAE)。
  • 与误差尺度的关系: δ 的值应该与你的数据集中误差的典型尺度相匹配。如果你的误差通常很小,你可能需要一个较小的 δ。如果误差分布比较宽泛,你可能需要一个较大的 δ。
  • 平衡鲁棒性与收敛性:
    • 较小的 δ 使 Hubery 损失更接近 MAE,对异常值更鲁棒,但可能在零点附近收敛较慢或不稳定。
    • 较大的 δ 使 Hubery 损失更接近 MSE,对正常误差更敏感,收敛可能更快,但对异常值更不鲁棒。

    选择 δ 就是在鲁棒性和收敛速度之间做出权衡。

实践中如何选择 δ:

通常,δ 是通过以下方法来选择的:

  1. 交叉验证/网格搜索: 将 δ 作为一个超参数,在合理的范围内尝试不同的值(例如,[0.1, 0.5, 1.0, 2.0, 5.0] 或者基于误差分布的统计量来选取),然后通过交叉验证评估模型在验证集上的性能(例如,使用MSE、MAE或其他评估指标),选择表现最好的 δ 值。
  2. 基于误差分布的启发式方法: 有些经验法则建议 δ 可以基于训练数据误差的分布来选择,例如选择 δ 为所有样本绝对误差的中位数、某个百分位数(如10%或20%)或者基于误差的标准差乘以一个常数。这种方法需要先用一个初步模型(比如用MSE或MAE)训练一次,计算其预测误差,然后分析这些误差的分布来确定 δ。
  3. 领域知识: 如果对数据的误差特性有先验知识,可以根据这些知识来设定 δ 的大致范围。

最终选择哪个 δ 值,取决于具体任务的要求以及通过实验验证得到的最佳效果。

【huber损失】如何在代码中实现?

主流的机器学习库通常都内置了对Huber损失的支持,无需从头手写分段函数。这使得在实践中应用Huber损失非常便捷。

  • Scikit-learn (Python):

    在Scikit-learn的回归模型中,有些模型直接支持Huber损失作为可选参数,例如 `sklearn.linear_model.HuberRegressor` 就是专门实现基于Huber损失的线性回归模型,其中 `epsilon` 参数就是 δ。

    对于其他模型,比如梯度提升树 `GradientBoostingRegressor` 或 `HistGradientBoostingRegressor`,它们允许指定损失函数,但通常内置的损失函数是 `’squared_error’` 或 `’absolute_error’`。要使用Huber损失,你可能需要查看库的文档,或者使用更底层的库。

  • TensorFlow 和 PyTorch (Python):

    深度学习框架TensorFlow和PyTorch都提供了内置的Huber损失函数。它们通常命名为 `Huber` 或 `smooth_l1_loss` (这是一种与Huber损失非常相似或等价的变体,参数含义可能略有不同)。

    • TensorFlow: `tf.keras.losses.Huber(delta=…)` 或 `tf.compat.v1.losses.huber_loss(labels, predictions, delta=…)`
    • PyTorch: `torch.nn.HuberLoss(delta=…)` 或 `torch.nn.functional.smooth_l1_loss(input, target, beta=…)` (PyTorch的 `smooth_l1_loss` 中的 `beta` 参数等同于 Huber 损失中的 δ)。

    在这些框架中,你只需要在模型编译或定义训练步骤时,将损失函数指定为相应的Huber损失类或函数,并设置 δ 参数即可。

使用这些库提供的接口,可以方便地将Huber损失集成到你的机器学习项目中。

总结

Huber损失是一个在鲁棒性和优化效率之间取得良好平衡的回归损失函数。通过在小误差时使用二次惩罚和大误差时使用线性惩罚,它有效地减轻了异常值对模型训练的负面影响,同时保持了在最优值附近的光滑性,有助于模型稳定快速地收敛。理解其定义、为何使用、如何计算梯度以及如何选择关键参数 δ,是成功应用Huber损失解决实际回归问题的关键。