标题说明了一切:PyTorch中有一个与TensorFlow的tf.nn.softmax_cross_entropy_with_logits相同的损失函数吗?
谢谢。
答案 0 :(得分:1)
TyorFlow的
softmax_cross_entropy_with_logits
的PyTorch中的等效损失函数
torch.nn.functional.cross_entropy
将logits作为输入(内部执行log_softmax)。在这里,logit只是[0,1]
间隔之外的一些非概率值。
但是,logits也是将转换为概率的值。 如果您考虑tensorflow函数的名称,您会理解它是pleonasm。
因为with_logits
部分假设将调用softmax
。
在PyTorch中,实现如下所示:
loss = F.cross_entropy(x, target)
相当于:
lp = F.log_softmax(x, dim=-1)
loss = F.nll_loss(lp, target)
它不是F.binary_cross_entropy_with_logits
,因为此函数假定了多标签分类:
F.sigmoid + F.binary_cross_entropy = F.binary_cross_entropy_with_logits
它也不是torch.nn.functional.nll_loss
,因为此函数采用对数概率(在log_softmax()
之后)而不是对数。
答案 1 :(得分:0)
在多个线程中遵循指针之后,我得到了以下转换。我会将解决方案放在这里,以防其他人落入此线程。它是从here修改而来的,其行为在this context中符合预期。
# pred is the prediction with shape [C, H*W]
# gt is the target with shape [H*W]
# idx is the boolean array on H*W for masking
# Tensorflow version
loss = tf.nn.sparse_softmax_cross_entropy_with_logits( \
logits=tf.boolean_mask(pred, idx), \
labels=tf.boolean_mask(gt, idx)))
# Pytorch version
logp = torch.nn.functional.log_softmax(pred[idx])
logpy = torch.gather(logp, 1, Variable(gt[idx].view(-1,1)))
loss = -(logpy).mean()
答案 2 :(得分:0)
@Blade这是我想出的解决方案!
import torch
import torch.nn as nn
import torch.nn.functional as F
class masked_softmax_cross_entropy_loss(nn.Module):
r"""my version of masked tf.nn.softmax_cross_entropy_with_logits"""
def __init__(self, weight=None):
super(masked_softmax_cross_entropy_loss, self).__init__()
self.register_buffer('weight', weight)
def forward(self, input, target, mask):
if not target.is_same_size(input):
raise ValueError("Target size ({}) must be the same as input size ({})".format(target.size(), input.size()))
input = F.softmax(input)
loss = -torch.sum(target * torch.log(input), 1)
loss = torch.unsqueeze(loss, 1)
mask /= torch.mean(mask)
mask = torch.unsqueeze(mask, 1)
loss = torch.mul(loss, mask)
return torch.mean(loss)
顺便说一句:当时(2017年9月),我需要此损失函数,因为我试图将Thomas Kipf的GCN代码(请参见https://arxiv.org/abs/1609.02907)从TensorFlow转换为PyTorch。但是,我现在注意到Kipf自己完成了此操作(请参见https://github.com/tkipf/pygcn),在他的代码中,他只是使用内置的PyTorch损失函数,即负对数似然损失,即
loss_train = F.nll_loss(output[idx_train], labels[idx_train])
希望这会有所帮助。
〜DV
答案 3 :(得分:0)
解决方案
from thexp.calculate.tensor import onehot
from torch.nn import functional as F
import torch
logits = torch.rand([3,10])
ys = torch.tensor([1,2,3])
targets = onehot(ys,10)
assert F.cross_entropy(logits,ys) == -torch.mean(torch.sum(F.log_softmax(logits, dim=1) * targets, dim=1))
onehot功能:
def onehot(labels: torch.Tensor, label_num):
return torch.zeros(labels.shape[0], label_num, device=labels.device).scatter_(1, labels.view(-1, 1), 1)