pytorch 自定义损失函数 nn.CrossEntropyLoss
pytorch custom loss function nn.CrossEntropyLoss
学习了autograd后,尝试自己制作损失函数。
这是我的损失
def myCEE(outputs,targets):
exp=torch.exp(outputs)
A=torch.log(torch.sum(exp,dim=1))
hadamard=F.one_hot(targets, num_classes=10).float()*outputs
B=torch.sum(hadamard, dim=1)
return torch.sum(A-B)
和我比较torch.nn.CrossEntropyLoss
这是结果
for i,j in train_dl:
inputs=i
targets=j
break
outputs=model(inputs)
myCEE(outputs,targets) : tensor(147.5397, grad_fn=<SumBackward0>)
loss_func = nn.CrossEntropyLoss(reduction='sum') : tensor(147.5397, grad_fn=<NllLossBackward>)
值相同。
我想,因为那些是不同的功能所以 grad_fn 是不同的,它
不会造成任何问题。
但是出事了!
4个epoch后,损失值变为nan
。
与myCEE
相反,nn.CrossEntropyLoss学习进展顺利。
所以,请问是不是我的功能有问题
在阅读了一些关于 nan
问题的帖子后,我在模型中添加了更多的卷积层。
结果39个epoch的训练没有出错
尽管如此,我想知道 myCEE 和 nn.CrossEntropyLoss
之间的区别
torch.nn.CrossEntropyLoss
与您的实现不同,因为它在使用大数值时使用了一个技巧来对抗指数的不稳定计算。给定 logits 输出 {l_1, ... l_j, ..., l_n}
,softmax 定义为:
softmax(l_i) = exp(l_i) / sum_j(exp(l_j))
诀窍是将分子和分母乘以 exp(-β)
:
softmax(l_i) = exp(l_i)*exp(-β) / [sum_j(exp(l_j))*exp(-β)]
= exp(l_i-β) / sum_j(exp(l_j-β))
然后 log-softmax 归结为:
logsoftmax(l_i) = l_i - β - log[sum_j(exp(l_j-β))]
在实践中 β
被选为最高 logit 值 即 β = max_j(l_j)
.
您可以在这个问题上阅读更多相关信息:。
学习了autograd后,尝试自己制作损失函数。 这是我的损失
def myCEE(outputs,targets):
exp=torch.exp(outputs)
A=torch.log(torch.sum(exp,dim=1))
hadamard=F.one_hot(targets, num_classes=10).float()*outputs
B=torch.sum(hadamard, dim=1)
return torch.sum(A-B)
和我比较torch.nn.CrossEntropyLoss
这是结果
for i,j in train_dl:
inputs=i
targets=j
break
outputs=model(inputs)
myCEE(outputs,targets) : tensor(147.5397, grad_fn=<SumBackward0>)
loss_func = nn.CrossEntropyLoss(reduction='sum') : tensor(147.5397, grad_fn=<NllLossBackward>)
值相同。
我想,因为那些是不同的功能所以 grad_fn 是不同的,它 不会造成任何问题。
但是出事了!
4个epoch后,损失值变为nan
。
与myCEE
相反,nn.CrossEntropyLoss学习进展顺利。
所以,请问是不是我的功能有问题
在阅读了一些关于 nan
问题的帖子后,我在模型中添加了更多的卷积层。
结果39个epoch的训练没有出错
尽管如此,我想知道 myCEE 和 nn.CrossEntropyLoss
之间的区别torch.nn.CrossEntropyLoss
与您的实现不同,因为它在使用大数值时使用了一个技巧来对抗指数的不稳定计算。给定 logits 输出 {l_1, ... l_j, ..., l_n}
,softmax 定义为:
softmax(l_i) = exp(l_i) / sum_j(exp(l_j))
诀窍是将分子和分母乘以 exp(-β)
:
softmax(l_i) = exp(l_i)*exp(-β) / [sum_j(exp(l_j))*exp(-β)]
= exp(l_i-β) / sum_j(exp(l_j-β))
然后 log-softmax 归结为:
logsoftmax(l_i) = l_i - β - log[sum_j(exp(l_j-β))]
在实践中 β
被选为最高 logit 值 即 β = max_j(l_j)
.
您可以在这个问题上阅读更多相关信息: