pytorch中loss函数问题记录

文章转载于:pytorch中二分类和多分类问题记录篇2

在pytorch中和keras不同的是如果使用torch.nn.CrossEntropyLoss()交叉熵作为损失函数,并不需要我们进行one-hot编码,因为已经替我们执行了这一操作,只需要我们传入的label是longtensor即可。

  • input : 模型输出,包含每个类的得分,2-D tensor,shape为 batch * n类
  • target: 大小为 n 的 1—D tensor,包含类别的索引(0到 n-1)。
    注意CrossEntropyLoss()的target输入也是类别值,不是one-hot编码格式
 
import numpy as np
import torch
import torch.nn.functional as F
 
 
# 比如这是一个模型的输出,本案例为一个三类别的分类,共有四组样本,如下:
pred_y = np.array([[ 0.30722019 ,-0.8358033 ,-1.24752918],
                   [ 0.72186664 , 0.58657704 ,-0.25026393],
                   [ 0.16449865 ,-0.44255082 , 0.68046693],
                   [-0.52082402 , 1.71407838 ,-1.36618063]])
pred_y=torch.from_numpy(pred_y)
 
# 真实的标签如下所示
true_y = np.array([[ 1 , 0 , 0],
                   [ 0 , 1 , 0],
                   [ 0 , 1 , 0],
                   [ 0 , 0 , 1]])
true_y=torch.from_numpy(true_y)
target = np.argmax(true_y, axis=1) #(4,) #其实就是获得每一给类别的整数值,这个和tensorflow里面不一样哦 内部会自动转换为one-hot形式
target = torch.LongTensor(target)  #(4,)
 
print(target)            # tensor([0,1,1,2])
print("-----------------------------------------------------------")
 
# 第一步:使用激活函数softmax进行缩放
print("第一步:使用激活函数softmax进行缩放")
pred_y = F.softmax(pred_y,dim=1)
print(pred_y)
print('-----------------------------------------------------------')
 
# 第二步:对每一个缩放之后的值求对数log
print("第二步:对每一个缩放之后的值求对数log")
pred_y=torch.log(pred_y)
print(pred_y)
print('-----------------------------------------------------------')
 
# 第三步:求交叉熵损失
loss=F.nll_loss(pred_y,target)
print(loss)  # 最终的损失为:tensor(1.5929, dtype=torch.float64)
 
print('-----------------------------------------------------------')
print("两部实现交叉熵")
# 第一步:直接使用log_softmax,相当于softmax+log
pred_y=F.log_softmax(pred_y,dim=1)
print(pred_y)
print('-----------------------------------------------------------')
 
# 第二步:求交叉熵损失
loss=F.nll_loss(pred_y,target)
print(loss) # tensor(1.5929, dtype=torch.float64)
print('-----------------------------------------------------------')
 
 
print("一步实现")
# 第一步:求交叉熵损失一步到位
loss=F.cross_entropy(pred_y,target)
print(loss) 
 
print('-----------------------------------------------------------')
# https://blog.csdn.net/qq_29631521/article/details/104907401
# https://www.cnblogs.com/cxq1126/p/13794877.html
import torch
import torch.nn as nn
import torch.nn.functional as F
 
m = nn.Sigmoid()
 
loss_f1 = nn.BCELoss()
loss_f2 = nn.BCEWithLogitsLoss()
loss_f3 = nn.CrossEntropyLoss()
 
logits = torch.randn(3, 2)
labels = torch.FloatTensor([[0, 1], [1, 0], [1, 0]])
 
print(loss_f1(m(logits), labels))      #tensor(0.9314),注意logits先被激活函数作用
print(loss_f2(logits, labels))         #tensor(0.9314)
 
label2 = torch.LongTensor([1, 0, 0])
print(loss_f3(logits, label2))         #tensor(1.2842)
 
# 如果label2也想变成labels,然后通过BCELoss进行计算的话,可以先转变成独热编码的形式:
encode = F.one_hot(label2, num_classes = 2) 
print("encode: ",encode)              #encode的值和labels一样,但是类型是LongTensor
print(loss_f1(m(logits), encode.type(torch.float32)))     #tensor(0.9314)

参考:https://www.cnblogs.com/marsggbo/p/10401215.html

https://segmentfault.com/a/1190000023336609?utm_source=tag-newest

在pytorch中和keras不同的是如果使用torch.nn.CrossEntropyLoss()交叉熵作为损失函数,并不需要我们进行one-hot编码,因为已经替我们执行了这一操作,只需要我们传入的label是longtensor即可。

  • input : 模型输出,包含每个类的得分,2-D tensor,shape为 batch * n类
  • target: 大小为 n 的 1—D tensor,包含类别的索引(0到 n-1)。
    注意CrossEntropyLoss()的target输入也是类别值,不是one-hot编码格式

猜你喜欢

转载自blog.csdn.net/Acmer_future_victor/article/details/110678012