class BCELoss(_WeightedLoss):
def __init__(self, weight=None, size_average=True, reduce=True):
super(BCELoss, self).__init__(weight, size_average, reduce)
def forward(self, input, target):
_assert_no_grad(target)
return F.binary_cross_entropy(input, target, weight=self.weight,
size_average=self.size_average,
reduce=self.reduce)
It Creates a criterion that measures the Binary Cross Entropy between the target and the output; This is used for measuring the error of a reconstruction in for example an auto-encoder. Note that the targets `y` should be numbers between 0 and 1(y={0,1})
对于N个样本,input=x,target=y公式就是:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0AjN0ITM0MTM3ITNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
这里的N就是batch的数目
参数 reduces默认为True,那么:
对于loss取平均值具体的:
参数input的shape=‘(N,*)’,*代表任何一个额外的维度,注意对于BCELoss必须保证其输入的参数都位于0到1之间,无论是标签还是预测值,如果不想让预测值必须位于0到1之间则可以采用BCEWithLogitsLoss损失函数。
参数target的shape和input的shape是一样的,里面的值只能是0或者1
输出output,如果reduce是True则是一个常数,否则和input的形状一样。
所以input的值并不是由softmax得来的,而是sigmoid或者是其他的对单个属性进行归一化。
举例:
import torch
import torch.nn as nn
m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3, requires_grad=True)
target = torch.empty(3).random_(2) # target的值只能是0或者1,形状和input的形状是一样的
output = loss(m(input), target)
output.backward()
举例:可以这么认为这个函数的作用,处理多标签任务,但是每一类标签只能是二分类也就是0和1,或者说可以处理每一个像素点的分类,只能是0和1.因此,对于GAN训练来说,如果D判别器输出是sigmoid的Batchx1或者是sigmoid输出
Batch x H_out x W_out那么就是对于每一个像素都是二分类。也可以用来做比如一张人脸需要输出标签性别(男,女),配戴眼镜(是,否),戴帽子(是,否),表情(微笑,严肃)等二分类标签。
import torch
import torch.nn as nn
lable=torch.tensor([
[ 1., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]
])
fc_out=torch.tensor([
[2.5,-2,0.8989],
[3,0.8,-842],
[0.00000000000001,2,4.9]
])
# 使用函数得到的loss
loss = nn.CrossEntropyLoss()
l=loss(fc_out,lable)
print(l) # tensor(0.8327)
# 将上面的函数编写出来
sigmoid_fc=1/(1+torch.exp(-fc_out))
def binary_cross_entropyloss(prob,target,reduce=True):
loss = -(lable*(torch.log(sigmoid_fc+1e-7))+(1-lable)*(torch.log(1-sigmoid_fc+1e-7)))
if reduce:
loss=torch.sum(loss)/torch.numel(lable) # 得到元素个数
return loss
loss=binary_cross_entropyloss(sigmoid_fc,lable)
print(loss) # tensor(0.8327)