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

记录torch.nn.CrossEntropyLoss()和torch.nn.BCELoss,第1张

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

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能力有限,先到这里吧。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/943677.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存