PyTorch 相当于 tf.nn.softmax_cross_entropy_with_logits 和 tf.nn.sigmoid_cross_entropy_with_logits
PyTorch equivalent to tf.nn.softmax_cross_entropy_with_logits and tf.nn.sigmoid_cross_entropy_with_logits
我找到了 post 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: 1D target tensor expected, multi-target not supported
看来问题还是没有解决。如何在 PyTorch 中实现 tf.nn.softmax_cross_entropy_with_logits
?
tf.nn.sigmoid_cross_entropy_with_logits
呢?
- tf.nn.softmax_cross_entropy_with_logits
编辑: 这实际上不等同于 F.cross_entropy
. The latter can only handle the single-class classification setting. Not the more general case of multi-class classification, whereby the label can be comprised of multiple classes. Indeed, F.cross_entropy
将唯一的 class id 作为目标(每个实例), 不classes 上的概率分布,因为 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 然后是负对数似然,将每个 class 视为二进制 class化任务:
>>> 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
。
我找到了 post 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: 1D target tensor expected, multi-target not supported
看来问题还是没有解决。如何在 PyTorch 中实现 tf.nn.softmax_cross_entropy_with_logits
?
tf.nn.sigmoid_cross_entropy_with_logits
呢?
- tf.nn.softmax_cross_entropy_with_logits
编辑: 这实际上不等同于 F.cross_entropy
. The latter can only handle the single-class classification setting. Not the more general case of multi-class classification, whereby the label can be comprised of multiple classes. Indeed, F.cross_entropy
将唯一的 class id 作为目标(每个实例), 不classes 上的概率分布,因为 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 然后是负对数似然,将每个 class 视为二进制 class化任务:
>>> 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
。