请参阅Sklearn中的对数损失和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.])))
答案 0 :(得分:0)
实际上,我发现了。事实证明,当权重的总和大于输入数组的维数时,BCELoss和log_loss的行为有所不同。有趣。
答案 1 :(得分: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合并为一个 类。此版本比使用普通版本在数值上更稳定 乙状结肠后跟BCELoss,方法是将操作合并为一个 层,我们利用log-sum-exp技巧进行数值计算 稳定性。