Focal Loss

Focal Loss(焦点损失)是为了解决**极度类别不平衡(Class Imbalance)**问题而设计的损失函数,最早由何恺明团队在 RetinaNet 论文中提出。

为什么需要Focal Loss

在训练分类器(尤其是目标检测)时,往往存在两个问题:

  1. 正负样本不平衡: 比如在一张图里,背景(负样本)占了绝大多数,目标(正样本)很少。
  2. 难易样本不平衡: 大多数背景都很容易区分(Easy Negatives),模型这部分学得很好;但少部分样本很难区分(Hard Examples)。

如果使用普通的交叉熵损失(Cross Entropy, CE),那些大量的、容易分类的样本虽然单个Loss很小,但加起来会淹没掉少数的、难分类样本的Loss,导致模型学偏了。

数学公式

$$
FL(p_t) = -\alpha_t (1 - p_t)^\gamma \log(p_t)
$$

调整

Gamma

解决“难易不平衡”。当模型只学简单的,不学难的时候调整

情况 A:需要 调大 Gamma (比如从 2.0 -> 3.0 或 4.0)

  • 现象: 模型的 Loss 下降很快,但准确率(mAP 或 Accuracy)就是上不去。
    • 原因: 这说明大量的“简单背景”或“容易区分的负样本”虽然 Loss 很小,但因为数量太庞大,它们加起来的总 Loss 依然主导了梯度,让模型觉得“我已经学得很好了”,从而不再去优化那些真正困难的样本。
  • 现象: 模型对由于遮挡、模糊、光照差导致的目标检测效果很差。
    • 对策: 调大 Gamma,进一步压低简单样本的权重,强迫模型去“啃硬骨头”。

情况 B:需要 调小 Gamma (比如从 2.0 -> 1.0 或 0.5)

  • 现象: 模型训练不稳定,Loss 震荡,或者难以收敛。
    • 原因: 可能是 Gamma 太大,导致过多的简单样本 Loss 被清零,模型能学到的有效信息太少;或者是那些被认为是“难样本”的其实是**离群点(Outliers)*或*脏数据(标错了)。如果过度关注这些脏数据,模型就会学坏。
  • 现象: 简单的任务(Easy Task)。
    • 如果你的数据集本身背景很干净,目标很清晰,不需要太强的 Focal Loss,调小 Gamma 接近 0(即接近 Cross Entropy)可能效果更好。

Alpha

核心目的: 简单粗暴地平衡正负样本的数量差异,或者调节 Precision(精确率)和 Recall(召回率)的偏好。

情况 A:正负样本比例极度悬殊

  • 场景: 类似于欺诈检测、极小目标检测(背景像素占比 99.9%)。
  • 调整方向: 理论上应该给少类(正样本)更大的权重。但是!在 Focal Loss 中有一个反直觉的经验:
    • 如果你的背景(负样本)特别多,你反而应该把正样本的 Alpha 设得小一点(比如 0.25 而不是 0.75)。
    • 为什么? 因为正样本通常很少且较难(Loss大),而负样本虽然多但通常很简单(Loss会被 Gamma 压得很低)。如果 Alpha 给正样本太大,可能会导致模型过于激进地预测为正类,产生大量误报(False Positives)。

情况 B:调节指标偏好 (Precision vs Recall)

  • 如果你希望提高 Recall(宁可错杀,不可放过):
    • 调大 Alpha(增加正样本权重)。模型会因为害怕漏掉正样本而受到更大的惩罚,因此会更倾向于预测“是”。
  • 如果你希望提高 Precision(宁缺毋滥):
    • 调小 Alpha(减小正样本权重,或者说相对增加负样本权重)。模型会变得保守,只有非常有把握时才预测为“是”。

Gamma 和 Alpha 的联动调整

Gamma越大,Alpha应当越小

原理: 当你调大 Gamma 时,你已经大幅度抑制了大量简单负样本(背景)的 Loss。此时,正样本在总 Loss 里的占比其实已经变相增加了。如果你不把 Alpha 调小一点,正样本的权重就会变得“过大”,导致训练不稳定或误报增多。

经典的实验数值(来自 RetinaNet 论文):

Gamma (γ) Alpha (α) 说明
0 (CE Loss) 0.75 没有 Gamma 抑制时,需要用较大的 Alpha 来平衡数量
2.0 (标准) 0.25 最常用的组合,Gamma 抑制了易分样本,Alpha 适当减小
5.0 (强聚焦) 0.05 - 0.1 Gamma 极强时,Alpha 必须设得很小

实战调参策略

如果不知道怎么设,建议按照这个顺序来:

  1. 先固定 Alpha,调 Gamma:
    • 先设 alpha=0.25(或者用你数据集中正负样本比例的倒数,但不要超过 0.5)。
    • 尝试 gamma = [1.0, 2.0, 3.0]
    • 看验证集 mAP 哪个最高。通常 2.0 是最稳健的起点。
  2. 固定 Gamma,微调 Alpha:
    • 选定最佳 Gamma 后(比如 2.0),微调 alpha
    • 比如尝试 [0.20, 0.25, 0.30]
    • 观察模型的误报率漏检率来决定往哪边偏。

一句话总结: 觉得模型太笨(学不会难的)就动 Gamma;觉得模型太偏科(正负失衡或误报太多)就动 Alpha