【问题标题】:How to implement FocalLoss in Pytorch?如何在 Pytorch 中实现 FocalLoss?
【发布时间】:2021-06-03 08:54:30
【问题描述】:

Focal Loss 是一种损失,旨在解决分类任务的类别不平衡问题。

这是我的尝试

class FocalLoss(nn.Module):
    def __init__(
            self,
            weight=None,
            gamma=2.,
            reduction='none'
    ):
        nn.Module.__init__(self)
        self.weight = weight
        self.gamma = gamma
        self.reduction = reduction

    def forward(self, input_tensor, target_tensor):
        log_prob = F.log_softmax(input_tensor, dim=-1)
        prob = torch.exp(log_prob)
        return F.nll_loss(
                ((1 - prob) ** self.gamma) * log_prob,
                target_tensor,
                weight=self.weight,
                reduction=self.reduction
        )

loss.backward() 这给了

raise RuntimeError("grad can be implicitly created only for scalar outputs")
RuntimeError: grad can be implicitly created only for scalar outputs

这是对损失函数的调用:

loss = self._criterion(log_probs, label_batch)

self._criterion = nn.CrossEntropyLoss() 有效,self._criterion = FocalLoss() 报错。

如何使这种损失表现得像 CrossEntropyLoss API-wise?

【问题讨论】:

  • AFAIK 在尝试区分返回张量而不是标量的函数时会出现此类错误。因此,您的 forward 函数可能会返回一个张量
  • @ForceBru 请参阅编辑。我只想要类似于CrossEntropyLoss 的行为

标签: python machine-learning deep-learning pytorch loss-function


【解决方案1】:

reduction='none'

这是罪魁祸首。查看 CrossEntropyLoss ,您将看到默认值为 减少='平均'。这意味着 XELoss 的输出是一个只有一个元素的张量; [1, 2] 变为 [1.5]。您不能在其中包含多个元素的张量上按原样调用 .backward() 。我建议将其更改为 XELoss 中的“平均”。

这背后的想法是 .backward() 计算某个数字的梯度。所以如果你有“2x”并调用backward(),关于2的梯度是x,关于x的梯度是2。另一方面,如果你有x * [1, 2]并且你调用向后,计算向量的梯度并不合适;相反,您将计算雅可比行列式。

【讨论】:

    猜你喜欢
    • 2020-12-14
    • 1970-01-01
    • 2022-11-05
    • 2020-08-06
    • 2021-01-29
    • 2021-03-17
    • 1970-01-01
    • 2018-10-14
    • 2018-10-01
    相关资源
    最近更新 更多