记录torch.nn.CrossEntropyLoss()和torch.nn.BCELoss()区别

小白在这里弱弱记录一下区别,哪里不对请指教

torch.nn.BCELoss()

区别有以下三点:

  1. label是float类型
  2. 输出为1维或者[batch,1]
  3. y_pred和label的大小保持一致
  4. 补充一点:使用BCELoss的时候网络最后一层需要是Sigmoid()函数,否则会报这个错:RuntimeError: CUDA error: device-side assert triggered ,或者可以使用BCEWithLogitsLoss函数替换BCELoss就不用加sigmoid层了
x_data = torch.Tensor([[45,64],[66,88],[78,70],[55,23],[88,66],[44,34],[49,59],[64,62],[100,60]])
y_data = torch.Tensor([[0],[1],[1],[0],[0],[1],[0]])       #区别1:float类型


class LogicalRegressionModel(torch.nn.Module):
    def __init__(self):
        super(LogicalRegressionModel, self).__init__()
        self.linear = torch.nn.Linear(2,1)				#区别2:仅输出每个样本的概率值

    def forward(self,x):
        x = F.sigmoid(self.linear(x))
        return x

model = LogicalRegressionModel()


criterion = torch.nn.BCELoss(size_average=False)
y_pred = model(x)
loss = criterion(y_pred,y)	# 区别3:y_pred与y要有相同的size!!

做一下预测,可以看到输出的是一个概率值,表示x这个分数63,22没有通过测试

x = torch.Tensor([63,22])
y_p = model(x)
print(y_p)
print(model(x).data)

if model(x).item()>=0.5:
    print('pass')
else:
    print('fail')

在这里插入图片描述

torch.nn.CrossEntropyLoss()

区别:

  1. label是long类型
  2. 输出为C维或者[batch,C]
  3. y_pred和label的大小不一致
x_data = torch.Tensor([[45,64],[66,88],[78,70],[55,23],[88,66],[44,34],[49,59],[64,62],[100,60]])
y_data = torch.LongTensor([[0],[1],[1],[0],[0],[1],[0],[1],[1]])		# 区别1:LongTensor

class LogicalRegressionModel(torch.nn.Module):
    def __init__(self):
        super(LogicalRegressionModel, self).__init__()
        self.linear = torch.nn.Linear(2,2)		# 区别2:输出的维度是Class的个数,此处是2分类,所以是2

    def forward(self,x):
        x = F.sigmoid(self.linear(x))
        return x

model = LogicalRegressionModel()
criterion = torch.nn.CrossEntropyLoss(size_average=False)    

 for x,y in zip(x_data,y_data):
    y_pred = model(x)
    y_pred = y_pred.view(1,-1)		#区别3:y_pred的大小[1, 2],label的大小[1];y_pred两列对应两个类别的概率,label是标签
    loss = criterion(y_pred,y)

做一下预测,可以看到输出的是每个类的概率值

x = torch.Tensor([63,33])		
a = model(x).data.view(-1,2)		#model(x)大小是[2],对应0/1两个概率值,a的大小是[1,2],a为了方便使用torch.max找最大值
_,predict = torch.max(a,dim=1)	    #较大值的索引值就是对应的标签值
print('predicet:',predict.item())	#0或者1

总结

BCELossCrossEntropyLoss
label是float类型label是Long类型
输出为1维或者[batch,1]输出为C维或者[batch,C]
y_pred和label的大小保持一致y_pred和label的大小不同
Sigmoid()函数

问题:如果做2分类到底哪个函数好用我至今也没搞懂?

用猫狗数据集测试:batch_size:4,train_data:22500,validation_data:2500
经过epoch一轮之后,没区别。。。一样的低,验证集上79%左右的准确率(一样),测试集上60%~70%的准确率==,GPU能力有限,先到这里吧。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值