【问题标题】:PyTorch equivalent to tf.nn.softmax_cross_entropy_with_logits and tf.nn.sigmoid_cross_entropy_with_logitsPyTorch 等效于 tf.nn.softmax_cross_entropy_with_logits 和 tf.nn.sigmoid_cross_entropy_with_logits
【发布时间】:2021-04-04 02:39:21
【问题描述】:

我找到了here 的帖子。在这里,我们尝试在 PyTorch 中找到 tf.nn.softmax_cross_entropy_with_logits 的等价物。答案仍然让我感到困惑。

这是Tensorflow 2 代码

import tensorflow as tf
import numpy as np

# here we assume 2 batch size with 5 classes

preds = np.array([[.4, 0, 0, 0.6, 0], [.8, 0, 0, 0.2, 0]])
labels = np.array([[0, 0, 0, 1.0, 0], [1.0, 0, 0, 0, 0]])


tf_preds = tf.convert_to_tensor(preds, dtype=tf.float32)
tf_labels = tf.convert_to_tensor(labels, dtype=tf.float32)

loss = tf.nn.softmax_cross_entropy_with_logits(logits=tf_preds, labels=tf_labels)

它给了我loss

<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1.2427604, 1.0636061], dtype=float32)>

这是PyTorch 代码

import torch
import numpy as np

preds = np.array([[.4, 0, 0, 0.6, 0], [.8, 0, 0, 0.2, 0]])
labels = np.array([[0, 0, 0, 1.0, 0], [1.0, 0, 0, 0, 0]])


torch_preds = torch.tensor(preds).float()
torch_labels = torch.tensor(labels).float()

loss = torch.nn.functional.cross_entropy(torch_preds, torch_labels)

但是,它提出了:

RuntimeError: 一维目标张量,不支持多目标

看来问题还是没有解决。如何在 PyTorch 中实现tf.nn.softmax_cross_entropy_with_logits

tf.nn.sigmoid_cross_entropy_with_logits 呢?

【问题讨论】:

    标签: python pytorch tensorflow2.0 softmax


    【解决方案1】:

    -tf.nn.softmax_cross_entropy_with_logits

    编辑:这实际上不等同于F.cross_entropy。后者只能处理单类分类设置。不是多类分类的更一般情况,标签可以由多个类组成。事实上,F.cross_entropy 将唯一的类 ID 作为目标(每个实例),不是类的概率分布,因为 tf.nn.softmax_cross_entropy_with_logits 可以预期接收。

    >>> logits = torch.tensor([[4.0, 2.0, 1.0], [0.0, 5.0, 1.0]])
    >>> labels = torch.tensor([[1.0, 0.0, 0.0], [0.0, 0.8, 0.2]])
    

    为了获得所需的结果,将 log-softmax 应用于您的 logits,然后取负对数似然:

    >>> -torch.sum(F.log_softmax(logits, dim=1) * labels, dim=1)
    tensor([0.1698, 0.8247])
    

    -tf.nn.sigmoid_cross_entropy_with_logits

    为此,您可以申请F.binary_cross_entropy_with_logits

    >>> F.binary_cross_entropy_with_logits(logits, labels, reduction='none')
    tensor([[0.0181, 2.1269, 1.3133],
            [0.6931, 1.0067, 1.1133]])
    

    相当于应用一个sigmoid然后负对数似然,将每个类视为一个二元分类任务:

    >>> labels*-torch.log(torch.sigmoid(logits)) + (1-labels)*-torch.log(1-torch.sigmoid(logits))
    tensor([[0.0181, 2.1269, 1.3133],
            [0.6931, 1.0067, 1.1133]])
    

    torch.nn.functional 导入为F

    【讨论】:

    • 感谢您的回答。知道如何在 Pytorch 中实现 tf.nn.sigmoid_cross_entropy_with_logits 吗?
    • 这比我想象的要复杂!但它在这里;)请参阅我编辑的答案。此外,我还冒昧地编辑了您的帖子以扩展您的问题,以供其他可能感兴趣的用户使用...
    • 此示例中 softmax_cross_entropy_with_logits 的结果不匹配:preds = [[4.0, 2.0, 1.0], [0.0, 5.0, 1.0]] labels = [[1.0, 0.0, 0.0], [0.0, 0.8, 0.2]]
    • 感谢您指出,确实torch.nn.cross_entropy 不等同于softmax_cross_entropy_with_logits,因为后者处理更一般的多类分类情况,即以多个标签作为目标。我已经相应地编辑了我的答案。
    猜你喜欢
    • 2019-08-29
    • 2021-08-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2020-10-30
    • 2022-06-30
    • 2021-03-16
    相关资源
    最近更新 更多