sklearn中的logloss和Pytorch中的BCEloss之间的区别?

问题描述 投票:0回答:2

查看Sklearn中的logloss和Pytorch中的BCEloss的文档,这些文档应该是相同的,即仅应用权重的正常日志丢失。但是,它们的行为不同 - 无论是否应用了权重。有谁可以向我解释一下?我找不到BCEloss的源代码(内部引用binary_cross_entropy)。

input = torch.randn((3, 1), requires_grad=True)
target = torch.ones((3, 1), requires_grad=False)
w = torch.randn((3, 1), requires_grad=False)

# ----- With weights
w = F.sigmoid(w)
criterion_test = nn.BCELoss(weight=w)
print(criterion_test(input=F.sigmoid(input), target=F.sigmoid(target)))
print(log_loss(y_true=target.detach().numpy(), 
               y_pred=F.sigmoid(input).detach().numpy(), sample_weight=w.detach().numpy().reshape(-1), labels=np.array([0.,1.])))
print("")
print("")
# ----- Without weights
criterion_test = nn.BCELoss()
print(criterion_test(input=F.sigmoid(input),target=F.sigmoid(target)))
print(log_loss(y_true=target.detach().numpy(), 
               y_pred=F.sigmoid(input).detach().numpy(), labels=np.array([0.,1.])))
scikit-learn pytorch loss-function cross-entropy
2个回答
0
投票

实际上,我发现了。事实证明,当权重总和超过输入数组的维度时,BCELoss和log_loss的行为会有所不同。有趣。


0
投票

关于没有权重的计算,使用BCEWithLogitsLoss得到的结果与sklearn.metrics.log_loss相同:

import torch
import torch.nn as nn
from sklearn.metrics import log_loss
import numpy as np

input = torch.randn((3, 1), requires_grad=True)
target = torch.ones((3, 1), requires_grad=False)

# ----- Without weights
criterion = torch.nn.BCEWithLogitsLoss()
criterion(input, target)
print('{:.6f}'.format(criterion(input, target)))
print('{:.6f}'.format((log_loss(y_true=target.detach().numpy(),
                                y_pred=torch.sigmoid(input).detach().numpy(),
                                labels=np.array([0.,1.])))))

注意:

这种损失将Sigmoid层和BCELoss组合在一个单独的类中。这个版本在数值上比使用普通的Sigmoid后跟BCELoss更稳定,因为通过将操作组合成一个层,我们利用log-sum-exp技巧来实现数值稳定性。

© www.soinside.com 2019 - 2024. All rights reserved.