IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 关于nn.BCEWithLogitsLoss()与nn.CrossEntropyLoss()的手动计算过程(都可用于多分类,不仅仅用于二分类) -> 正文阅读

[人工智能]关于nn.BCEWithLogitsLoss()与nn.CrossEntropyLoss()的手动计算过程(都可用于多分类,不仅仅用于二分类)

?使用nn.BCEWithLogitsLoss()

#pred和label都是2d的情况,行数表示有几个样本
#第1列是预测为标签0的分数,第2列是预测为标签1的分数,第3列是预测为标签2的概率,有3种标签
# 下面为nn.BCEWithLogitsLoss()的输入概率,和正确标签(float类型)的格式(输入概率和正确标签的shape相同,2d情况)
pred_1 = torch.tensor([[-0.2,0.6,0.4],
                      [0.2,0.1,0.5],
                      [0.3,0.8,0.9]])                       
label_1 = torch.tensor([[1,0,1],   #表示第一个样本既属于标签0也属于标签2
                        [1,0,0],   #表示第二个样本仅仅属于标签0
                        [0,1,1]])   #表示第三个样本既属于标签1也属于标签2

print('nn.BCEWithLogitsLoss())(pred,label) = ',nn.BCEWithLogitsLoss()(pred_1,label_1.float())) #tensor(0.6924)
print('nn.BCEWithLogitsLoss()(pred,label) = nn.BCELoss()(torch.sigmoid(pred),label)=',nn.BCELoss()(torch.sigmoid(pred_1),label_1.float()))
print('下面分3个步骤计算')
print('step 1,使用sigmoid归一化预测概率pred')
pred_1_sigmoid = torch.sigmoid(pred_1) #;print(pred_1_sigmoid)
# tensor([[0.4502, 0.6457, 0.5987],
#         [0.5498, 0.5250, 0.6225],
#         [0.5744, 0.6900, 0.7109]])
print('step 2,分别计算每个样本的损失')
#计算第一个样本的损失,第一个样本的标签为 (1,0,1)
sample_1_loss = -1*(1*torch.log(torch.tensor(0.4502)) + 0*torch.log(1-torch.tensor(0.4502)) +
              0*torch.log(torch.tensor(0.6457)) + 1*torch.log(1-torch.tensor(0.6457)) +
              1*torch.log(torch.tensor(0.5987)) +0*torch.log(1-torch.tensor(0.5987)))/3  
print('计算第一个样本的损失:',sample_1_loss) #tensor(0.7829)

#计算第二个样本的损失,第一个样本的标签为 (1,0,0)
sample_2_loss = -1*(1*torch.log(torch.tensor(0.5498)) + 0*torch.log(1-torch.tensor(0.5498)) +
              0*torch.log(torch.tensor(0.5250)) + 1*torch.log(1-torch.tensor(0.5250)) +
              0*torch.log(torch.tensor(0.6225)) +1*torch.log(1-torch.tensor(0.6225)))/3  
print('计算第二个样本的损失:',sample_2_loss) #tensor(0.7723)

#计算第仨个样本的损失,第一个样本的标签为 (0,1,1)
sample_3_loss = -1*(0*torch.log(torch.tensor(0.5744)) + 1*torch.log(1-torch.tensor(0.5744)) +
              1*torch.log(torch.tensor(0.6900)) + 0*torch.log(1-torch.tensor(0.6900)) +
              1*torch.log(torch.tensor(0.7109)) +0*torch.log(1-torch.tensor(0.7109)))/3  
print('计算第三个样本的损失:',sample_3_loss) #tensor(0.5222)


#三个样本平均损失
print('step 3,计算三个样本的平均损失:',(sample_1_loss+sample_2_loss+sample_3_loss)/3) #tensor(0.6924)

结果

nn.BCEWithLogitsLoss())(pred,label) =  tensor(0.6924)
nn.BCEWithLogitsLoss()(pred,label) = nn.BCELoss()(torch.sigmoid(pred),label)= tensor(0.6924)
下面分3个步骤计算
step 1,使用sigmoid归一化预测概率pred
step 2,分别计算每个样本的损失
计算第一个样本的损失: tensor(0.7829)
计算第二个样本的损失: tensor(0.7723)
计算第三个样本的损失: tensor(0.5222)
step 3,计算三个样本的平均损失: tensor(0.6924)

使用nn.CrossEntropyLoss()

#下面为nn.CrossEntropyLoss()的输入概率,和正确标签的格式(输入概率必须是2d,正确标签为1d,为每个样本正确类别的索引)
pred_2 = torch.tensor([[-0.2,0.6,0.4],
                      [0.2,0.1,0.5],
                      [0.3,0.8,0.3]]) 
#所有样本正确概率的ont_hot形式是下面的格式                      
# label_2 = torch.tensor([[0,0,1],   #必须是ont—hot形式,每个样本仅能属于一个类别
#                         [0,1,0],   
#                         [0,0,1]]) 
# 但是nn.CrossEntropyLoss()类的输入标签是下面1d的格式
label_2 = torch.tensor([2,1,2]) #表示第0个样本索引为2的元素对应正确标签3的概率,第1个样本索引为1的元素对应正确标签1的概率
print('nn.CrossEntropyLoss()(pred_2,label_2)=',nn.CrossEntropyLoss()(pred_2,label_2))
print('分步骤计算')
print('step 1,使用softmax归一化预测概率')
pred_softmax = torch.softmax(pred_2,dim=1)
# print(pred_softmax)
# tensor([[0.1981, 0.4409, 0.3610],
#         [0.3072, 0.2780, 0.4147],
#         [0.2741, 0.4519, 0.2741]])
print('step 2,求每个样本的损失')
sample_1_loss = -1*torch.log(pred_softmax[0,2]) ;print('第一个样本的损失',sample_1_loss) #tensor(1.0189)
sample_2_loss = -1*torch.log(pred_softmax[1,1]) ;print('第二个样本的损失',sample_2_loss) #tensor(1.2801)
sample_3_loss = -1*torch.log(pred_softmax[2,2]) ;print('第三个样本的损失',sample_3_loss) #tensor(1.2944)
print('step 3,所有样本的平均损失',(sample_1_loss+sample_2_loss+sample_3_loss)/3) #tensor(1.1978)

结果

nn.CrossEntropyLoss()(pred_2,label_2)= tensor(1.1978)
分步骤计算
step 1,使用softmax归一化预测概率
step 2,求每个样本的损失
第一个样本的损失 tensor(1.0189)
第二个样本的损失 tensor(1.2801)
第三个样本的损失 tensor(1.2944)
step 3,所有样本的平均损失 tensor(1.1978)

# 下面为nn.BCEWithLogitsLoss()的输入概率,和正确标签的格式为1d的情况)

# 下面为nn.BCEWithLogitsLoss()的输入概率,和正确标签的格式为1d的情况)
#即只有一个样本
pred_3 = torch.tensor([-0.2,0.6,0.4,0.5])
label_3 = torch.tensor([0,0,1,1])    #表示该样本既属于标签2也属于标签3
print(nn.BCEWithLogitsLoss()(pred_3,label_3.float()))
pred_3_sigmoid = torch.sigmoid(pred_3) ;print(pred_3_sigmoid)
# tensor([0.4502, 0.6457, 0.5987, 0.6225])
sample_loss =-1*(
              0*torch.log(pred_3_sigmoid[0]) + 1*torch.log(1-pred_3_sigmoid[0]) +
              0*torch.log(pred_3_sigmoid[1]) + 1*torch.log(1-pred_3_sigmoid[1]) +
              1*torch.log(pred_3_sigmoid[2]) + 0*torch.log(1-pred_3_sigmoid[2]) +
              1*torch.log(pred_3_sigmoid[3]) + 0*torch.log(1-pred_3_sigmoid[3]) 
)/4  #一个样本,4个类别,计算每个样本的损失除以类别的个数
print(sample_loss)

结果

tensor(0.6557)
tensor([0.4502, 0.6457, 0.5987, 0.6225])
tensor(0.6557)

总结:nn.BCEWithLogitsLoss()(pred,label)? label为float形式,pred和label同shape

自带归一化函数为sigmoid

nn.CrossEntropyLoss()(pred,label)? label为int形式,label为1dshape

自带归一化函数为softmax

番外篇

nn.BCEWithLogitsLoss(pred,label) = nn.BCELoss()(torch.sigmoid(pred),label)

当使用nn.BCELoss()(torch.softmax(pred,dim=1),label)时,并且标签为one_hot形式的2d标签,等同于标签为1d形式的nn.CrossEntroyLoss()(pred,label)

当nn.CrossEntroyLoss()分步骤计算使用sigmoid而不是softmax,有损失网络不会收敛,分类精度始终为50%左右

联系和区别:对一个样本的损失而言,nn.BCEWithLogitsLoss计算时sigmoid函数得到的归一化概率使得各个类别的概率没有产生关系,所以然后计算损失时,会计算所有类别产生的损失求平均,使得各个类别的概率强行产生联系,得到该样本的损失

对一个样本的损失而言,nn.CrossEntroyLoss()计算时softmax函数计算的归一化概率,就是各个类别的分数联合作用产生的归一化概率,即各个类别之间已经产生了联系,所以然后,会直接用这个正确索引对应的概率取负对数,得到该样本的损失

两种损失,nn.BCEWithLogitsLoss在得到归一化概率后,所有类别概率产生联系

nn.CrossEntroyLoss()在得到归一化概率前,所有类别分数产生联系

一前一后,都是为了使类别间产生联系的

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:15:35  更:2022-10-22 21:20:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:21:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码