【问题标题】:How to Use Class Weights with Focal Loss in PyTorch for Imbalanced dataset for MultiClass Classification如何在 PyTorch 中使用具有焦点损失的类权重来处理多类分类的不平衡数据集
【发布时间】:2021-02-21 08:15:09
【问题描述】:

我正在研究语言任务的多类分类(4 类),我正在使用 BERT 模型进行分类任务。我关注this blog as reference。 我的 BERT Fine Tuned 模型返回 nn.LogSoftmax(dim=1)。

我的数据非常不平衡,所以我使用sklearn.utils.class_weight.compute_class_weight 来计算类的权重并使用损失内的权重。

class_weights = compute_class_weight('balanced', np.unique(train_labels), train_labels)
weights= torch.tensor(class_weights,dtype=torch.float)
cross_entropy  = nn.NLLLoss(weight=weights) 

我的结果不太好,所以我想用Focal Loss 进行实验,并有一个 Focal Loss 的代码。

class FocalLoss(nn.Module):
  def __init__(self, alpha=1, gamma=2, logits=False, reduce=True):
    super(FocalLoss, self).__init__()
    self.alpha = alpha
    self.gamma = gamma
    self.logits = logits
    self.reduce = reduce

  def forward(self, inputs, targets):
    BCE_loss = nn.CrossEntropyLoss()(inputs, targets)

    pt = torch.exp(-BCE_loss)
    F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss

    if self.reduce:
      return torch.mean(F_loss)
    else:
      return F_loss

我现在有 3 个问题。首先也是最重要的是

  1. 我应该使用带焦点损失的类权重吗?
  2. 如果我必须在这个Focal Loss 中实现权重,我可以在 nn.CrossEntropyLoss() 中使用weights 参数
  3. 如果这个工具不正确,这个工具的正确代码应该是什么,包括权重(如果可能的话)

【问题讨论】:

    标签: python machine-learning deep-learning neural-network pytorch


    【解决方案1】:

    我认为您问题中的实现是错误的。 alpha 是类权重。

    在交叉熵中,类权重是 alpha_t,如以下表达式所示:

    你看到它是 alpha_t 而不是 alpha。

    在焦点损失中,公式是

    我们可以从this popular Pytorch implementation 看到,alpha 的作用与类权重相同。

    参考资料:

    1. https://amaarora.github.io/2020/06/29/FocalLoss.html#alpha-and-gamma
    2. https://github.com/clcarwin/focal_loss_pytorch

    【讨论】:

      【解决方案2】:

      我想 OP 现在应该已经得到了他的答案。我写这篇文章是为了其他可能会思考这个问题的人。

      在 OPs 实现 Focal Loss 中存在一个问题:

      1. F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss

      在这一行中,相同的alpha 值乘以每个类的输出概率,即 (pt)。此外,代码没有显示我们如何获得pt。 Focal Loss 的一个非常好的实现可以在 here 找到。但此实现仅适用于二进制分类,因为它在 self.alpha 张量中具有 alpha 和 1-alpha 两个类。

      在多类分类或多标签分类的情况下,self.alpha张量应包含等于标签总数的元素数。这些值可以是标签的反向标签频率或反向标签归一化频率(请注意频率为 0 的标签)。

      【讨论】:

        【解决方案3】:

        您可以通过以下方式找到问题的答案:

        1. Focal loss 自动处理类不平衡,因此 Focal loss 不需要权重。 alpha 和 gamma 因子处理焦点损失方程中的类别不平衡。
        2. 不需要额外的权重,因为焦点损失使用 alpha 和 gamma 调制因子来处理它们
        3. 根据焦点损失公式,您提到的实现是正确的,但我无法使我的模型与此版本收敛,因此,我使用了the following implementation from mmdetection framework
            pred_sigmoid = pred.sigmoid()
            target = target.type_as(pred)
            pt = (1 - pred_sigmoid) * target + pred_sigmoid * (1 - target)
            focal_weight = (alpha * target + (1 - alpha) *
                            (1 - target)) * pt.pow(gamma)
            loss = F.binary_cross_entropy_with_logits(
                pred, target, reduction='none') * focal_weight
            loss = weight_reduce_loss(loss, weight, reduction, avg_factor)
            return loss
        

        你也可以试试another focal loss version available

        【讨论】:

        • 假设是 softmax ?它的多类
        猜你喜欢
        • 2020-09-04
        • 2020-02-01
        • 2019-02-09
        • 2015-08-26
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        相关资源
        最近更新 更多