【问题标题】:soft cross entropy in pytorchpytorch中的软交叉熵
【发布时间】:2021-10-24 16:50:34
【问题描述】:

我在 pytorch 中实现软交叉熵损失时遇到了一点问题。

我需要为我的模型实现加权软交叉熵损失,这意味着目标值也是概率向量,而不是热向量。

我尝试按照一些论坛中的建议使用 kldivloss,但它不需要权重向量,所以我不能使用它。

总的来说,我对如何使用 pytorch 创建自定义损失函数以及 auto grad 如何遵循自定义损失函数感到有些困惑,尤其是在模型之后我们应用了一些不是数学的函数时,比如映射输出将模型转换为某个向量并计算映射向量的损失等。

【问题讨论】:

  • pytorch 正在使用反向传播来计算损失函数 w.r.t 可训练参数的梯度。这就是done
  • 你的问题太宽泛了,如果你想了解 PyTorch 自动微分背后的机制,那么你应该首先阅读更多相关信息(网上有很多有趣的文章,包括 Shai 链接你的那篇),然后你可以回来问更具体的问题。由于您在问题中提到了nn.KLDivLoss,如果您只是在寻找内置的softmax 交叉熵,那么nn.CrossEntropyLoss 应该可以完成这项工作!
  • 在这种情况下不能使用 pytorch 的交叉熵损失,因为 ptorch 交叉熵损失只接受硬标签,这意味着我不能将概率向量作为目标。并且 kldivloss 没有重量选项

标签: python deep-learning pytorch loss-function


【解决方案1】:

根据您的评论,您希望使用 soft 标签实现加权交叉熵损失。事实上,nn.CrossEntropyLoss 仅适用于 hard 标签(one-hot 编码),因为目标是作为密集表示提供的(每个实例只有一个类标签)。

您可以自己实现该功能。我最初在this answer 中实现了这种功能,但类上没有任何权重。在这里,我们采用以下三个参数:

  • logits:你的未缩放预测,
  • weights:每个 logit 的权重,以及
  • labels 你的目标张量。

我们有以下损失项:

>>> p = F.log_softmax(pred, 1)
>>> w_labels = weights*labels
>>> loss = -(w_labels*p).sum() / (w_labels).sum()

只要您使用可微分的 PyTorch 内置函数,您应该能够从自定义损失的输出中反向传递。在任何情况下,您都可以通过检查是否具有grad_fn 属性来验证是否可以从给定张量调用反向传递。


您可以将逻辑包装在 nn.Module

class SoftCrossEntropyLoss():
   def __init__(self, weights):
      super().__init__()
      self.weights = weights

   def forward(self, y_hat, y):
      p = F.log_softmax(y_hat, 1)
      w_labels = self.weights*y
      loss = -(w_labels*p).sum() / (w_labels).sum()
      return loss

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 2021-08-25
    • 2018-04-14
    • 2020-07-16
    • 2019-11-02
    • 2020-06-04
    • 2021-01-21
    • 2020-08-13
    • 2022-01-09
    相关资源
    最近更新 更多