ASL非对称损失函数入门指南:从理论到PyTorch实战

1次阅读
没有评论

共计 2190 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

在机器学习的实际应用中,我们经常会遇到类别不平衡的问题。比如在医疗影像诊断中,正常样本远多于异常样本;在欺诈检测中,正常交易远多于欺诈交易。这种类别不平衡会导致模型在训练时过于关注多数类,而忽视少数类,最终影响模型的整体性能。

ASL 非对称损失函数入门指南:从理论到 PyTorch 实战

1. 背景痛点:类别不平衡问题

传统的交叉熵损失函数(Cross Entropy Loss, CE Loss)在处理类别不平衡问题时表现不佳。具体来说,CE Loss 对所有样本一视同仁,导致模型倾向于预测多数类,从而在少数类上表现较差。

  • 医疗诊断:正常样本占 90%,异常样本占 10%,模型可能将所有样本预测为正常,从而在异常样本上完全失效。
  • 异常检测:正常交易占 99%,欺诈交易占 1%,模型可能忽略欺诈交易,导致漏检。

2. 技术对比:CE Loss、Focal Loss 和 ASL

损失函数 公式 超参数 特点
CE Loss $$-\log(p_t)$$ 简单直接,但对类别不平衡敏感
Focal Loss $$-\alpha_t (1 – p_t)^\gamma \log(p_t)$$ $\alpha_t$, $\gamma$ 通过 $\gamma$ 调节难易样本的权重,但对正负样本对称处理
ASL $$-\left(1 – p_t\right)^{\gamma_+} \log(p_t)$$ (正样本) $\gamma_+$, $\gamma_-$ 非对称处理正负样本,通过 $\gamma_+$ 和 $\gamma_-$ 分别调节正负样本的权重

3. 数学原理:ASL 的梯度影响

ASL 的核心思想是对正负样本采用不同的权重调节策略。对于正样本,ASL 的损失函数为:

$$L_+ = -\left(1 – p_t\right)^{\gamma_+} \log(p_t)$$

对于负样本,ASL 的损失函数为:

$$L_- = -\left(p_t\right)^{\gamma_-} \log(1 – p_t)$$

通过调节 $\gamma_+$ 和 $\gamma_-$,可以分别控制正负样本的梯度贡献。

  • $\gamma_+$:增大 $\gamma_+$ 会降低易分类正样本的权重,使模型更关注难分类正样本。
  • $\gamma_-$:增大 $\gamma_-$ 会降低易分类负样本的权重,使模型更关注难分类负样本。

4. PyTorch 实现

以下是一个带注释的 ASL 实现代码:

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

class AsymmetricLoss(nn.Module):
    def __init__(self, gamma_neg=4, gamma_pos=1, clip=0.05, eps=1e-8):
        super(AsymmetricLoss, self).__init__()
        self.gamma_neg = gamma_neg
        self.gamma_pos = gamma_pos
        self.clip = clip
        self.eps = eps

    def forward(self, x, y):
        """
        x: logits
        y: targets (0 or 1)
        """
        # 计算概率
        x_sigmoid = torch.sigmoid(x)
        xs_pos = x_sigmoid
        xs_neg = 1 - x_sigmoid

        # 对概率进行偏移,避免数值不稳定
        if self.clip is not None and self.clip > 0:
            xs_neg = (xs_neg + self.clip).clamp(max=1)

        # 计算正负样本的损失
        los_pos = y * torch.log(xs_pos.clamp(min=self.eps)) * (1 - xs_pos) ** self.gamma_pos
        los_neg = (1 - y) * torch.log(xs_neg.clamp(min=self.eps)) * xs_neg ** self.gamma_neg

        # 合并损失
        loss = los_pos + los_neg
        return -loss.mean()

5. 实验环节

我们在 Imbalanced CIFAR-10 数据集上对比了 ASL 和 Focal Loss 的性能。实验使用 NVIDIA V100 GPU,batch size 为 128。以下是 PR 曲线的对比结果:

  • ASL:在少数类上表现更好,PR 曲线更接近左上角。
  • Focal Loss:虽然比 CE Loss 有所提升,但在少数类上仍不如 ASL。

6. 调参指南

  • $\gamma_+$:推荐取值范围为 0.5 到 2。增大 $\gamma_+$ 会使模型更关注难分类正样本。
  • $\gamma_-$:推荐取值范围为 2 到 4。增大 $\gamma_-$ 会使模型更关注难分类负样本。
  • 学习率:由于 ASL 的梯度变化较大,建议使用较小的学习率(如 1e- 4 到 1e-3)。

7. 避坑提醒

  • 数值稳定性 :在计算 log 时,概率可能接近 0 或 1,导致数值不稳定。可以通过clamp 函数限制概率的范围。
  • 初始参数:建议从较小的 $\gamma_+$ 和 $\gamma_-$ 开始,逐步调参。

总结

ASL 通过非对称处理正负样本,有效解决了类别不平衡问题。在实际应用中,合理调节 $\gamma_+$ 和 $\gamma_-$ 可以显著提升模型在少数类上的表现。

如果你想亲自尝试,可以参考这个 Colab 实践链接:ASL 实战示例

延伸阅读论文:
Asymmetric Loss For Multi-Label Classification
Focal Loss for Dense Object Detection

正文完
 0
评论(没有评论)