试验记录:Pytorch损失函数BCELoss BCEWithLogitsLoss与CrossEntropyLoss

1. BCELoss与BCEWithLogitsLoss

在这里插入图片描述

def forward(self, input: Tensor, target: Tensor) -> Tensor:
    return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)

在这里插入图片描述

在这里插入图片描述

其中 c 是类别数(对于多标签二分类,c>1;对于单标签二分类,c=1),n 是批次中样本的数量,而 pc 是类别 c 的正向答案权重。

当 pc > 1 时,会增加召回率;当 pc < 1 时,会增加精确度。

例如,如果数据集包含单一类别的 100 个正例和 300 个负例,那么该类别的 pos_weight 应该等于 300 / 100 = 3。损失函数会如同数据集包含 3 × 100 = 300 个正例一样运作。

在这里插入图片描述

def forward(self, input: Tensor, target: Tensor) -> Tensor:
	 return F.binary_cross_entropy_with_logits(input, target, self.weight, pos_weight=self.pos_weight,reduction=self.reduction)

在这里插入图片描述

BCEWithLogitsLoss就是把Sigmoid-BCELoss合成一步。
结合了Sigmoid的BCELoss达到了BCEWithLogitsLoss相同的输出

import torch.nn.functional as F
import torch.nn as nn

pre = torch.tensor([[1.2, 0.2],[0.05,0.3]])
target = torch.tensor([[1., 0.],[0., 1.]]) 
#这里的pre和target都是二维的,BCE支持input是任意维度,只要保证pre和target维度相同
#例如
#pre = torch.tensor([[0.7, 0.2, 1.3],[0.5, 0.3, -2.0]])
#target = torch.tensor([[1., 0., 0.],[0., 1., 1.]]) 



sigmoid = nn.Sigmoid()
pre_sig = sigmoid(pre)

print(pre)
#tensor([[1.2000, 0.2000],[0.0500, 0.3000]])
print(pre_sig)
#tensor([[0.7685, 0.5498],[0.5125, 0.5744]])
print(target)
#tensor([[1., 0.],[0., 1.]])

loss = nn.BCELoss()
loss_sig = nn.BCEWithLogitsLoss()

print(loss(pre_sig, target))
#tensor(0.5836)
print(loss_sig(pre, target))
#tensor(0.5836)

2. CrossEntropyLoss

CrossEntropyLoss是把Softmax–Log–NLLLoss合并成一步,接受输入one-hot或者一维序号标签。

在图片单标签分类时,输入m张图片,输出一个mN的Tensor,其中N是分类个数。比如输入4张图片,分三类,最后的输出是一个43的Tensor

在这里插入图片描述

第1234行分别是第1234张图片的结果,假设第123列分别是猫、狗、猪的分类得分。 可以看出模型认为第234张都更可能是猫。

在这里插入图片描述

然后对每一行使用Softmax,这样可以得到每张图片的概率分布。

这里dim的意思是计算Softmax的维度,这里设置dim=1,可以看到每一行的加和为1。我们这里一张图片是一行,所以dim应该设置为1。

在这里插入图片描述

Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
NLLLoss的结果就是把上面的输出lg_sm与Label对应的那个值拿出来,再去掉负号,再求均值。

假设我们现在Target是[0,1,1,1](第一张图片是猫,第二三四张是狗)。第一行取第0个元素,第二行取第1个,第三行取第1个,第四行取第1个,去掉负号,结果是:[1.6558,2.3740,2.0454,1.9552]。再求个均值,结果是:

在这里插入图片描述

使用NLLLoss函数验证:

在这里插入图片描述

CrossEntropyLoss接受的输入

import torch.nn.functional as F
import torch.nn as nn

pre = torch.tensor([[0.8,0.2],[1.2,2.3],[0.9,1.12]])
target1 = torch.tensor([[1.,0.],[0.,1.],[0.,1.]])
target2 = torch.tensor([0,1,1])

loss = nn.CrossEntropyLoss()
print(loss(pre, target1))
print(loss(pre, target2))

#tensor(0.4380)
#tensor(0.4380)

参考文章:
https://blog.csdn.net/qq_22210253/article/details/85222093
https://blog.csdn.net/qq_22210253/article/details/85229988

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值