我找到了这里的帖子。在这里,我们试图找到tf.nn.softmax_cross_entropy_with_logits
在PyTorch中的等价性。答案仍然让我感到困惑。
这是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:一维目标张量期望,多目标不支持
看来这个问题还没有解决。如何在tf.nn.softmax_cross_entropy_with_logits
中实现PyTorch?
那tf.nn.sigmoid_cross_entropy_with_logits
呢
发布于 2020-12-26 17:23:06
- 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]])
为了获得所需的结果,将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]])
它相当于应用乙状结肠然后是负日志似然,将每个类视为二进制分类任务:
>>> 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
。
发布于 2022-10-12 13:25:38
nn.CrossEntropyLoss输出与tf.nn.softmax_cross_entropy_with_logits
相同
>>> import torch
>>> loss_fct = torch.nn.CrossEntropyLoss(reduction='none')
>>> 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]])
>>> preds = torch.from_numpy(preds)
>>> labels = torch.from_numpy(labels)
>>> loss_fct(preds, labels)
tensor([1.2428, 1.0636], dtype=torch.float64)
reduction
参数默认为意味着。我使它none
与您的输出匹配。
nn.BCEWithLogitsLoss输出与tf.nn.sigmoid_cross_entropy_with_logits
相同
>>> tf.nn.sigmoid_cross_entropy_with_logits(logits=tf_preds, labels=tf_labels)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy=
array([[0.91301525, 0.6931472 , 0.6931472 , 0.43748793, 0.6931472 ],
[0.37110066, 0.6931472 , 0.6931472 , 0.79813886, 0.6931472 ]],
dtype=float32)>
>>> loss_fct = torch.nn.BCEWithLogitsLoss(reduction='none')
>>> loss_fct(preds, labels, )
tensor([[0.9130, 0.6931, 0.6931, 0.4375, 0.6931],
[0.3711, 0.6931, 0.6931, 0.7981, 0.6931]], dtype=torch.float64)
https://stackoverflow.com/questions/65458736
复制相似问题