天天看点

torch.nn.BCELoss()=F.binary_cross_entropy()

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公式就是:

torch.nn.BCELoss()=F.binary_cross_entropy()

这里的N就是batch的数目

参数 reduces默认为True,那么:

torch.nn.BCELoss()=F.binary_cross_entropy()

对于loss取平均值具体的:

torch.nn.BCELoss()=F.binary_cross_entropy()

参数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)

 
           

继续阅读