共计 2190 个字符,预计需要花费 6 分钟才能阅读完成。
在机器学习的实际应用中,我们经常会遇到类别不平衡的问题。比如在医疗影像诊断中,正常样本远多于异常样本;在欺诈检测中,正常交易远多于欺诈交易。这种类别不平衡会导致模型在训练时过于关注多数类,而忽视少数类,最终影响模型的整体性能。

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
