在使用MIML的过程中,我需要对属于同一标签中的子概念进行损失值计算,采用的是nn.CrossEntropyLoss()交叉熵损失函数,然而我就出现上述这种情况,于是我自己写了一个小小的示例进行问题解决:
首先对正确的示例进行介绍:
import torch.nn as nn
import torch
func=nn.CrossEntropyLoss()
a=torch.Tensor([[ 0.0606,0.1610,0.2990,0.2101, 0.5104],
[0.6388,0.4053, 0.4196, 0.7060, 0.2793],
[ 0.3973,0.6114, 0.1127, 0.7732, 0.0592]])
b=[3,1,0]
b=torch.Tensor(b)
loss=func(a,b.long())
loss=func(a,b.long())
print("总loss:",loss)
首先我定义一个3*5行的矩阵作为神经网络的标签的预测值,然后定义一个b作为标签真实值,此时进行代码运行可以看到正确答案:
总loss: tensor(1.6690)
接着,我需要对a矩阵按行进行拆解,拆成一个一个的矩阵,然后分别对其进行损失值得计算,如下所示:
a1=torch.Tensor([ 0.0606,0.1610,0.2990,0.2101, 0.5104])
a2=torch.Tensor([0.6388,0.4053, 0.4196, 0.7060, 0.2793])
a3=torch.Tensor([ 0.3973,0.6114, 0.1127, 0.7732, 0.0592])
b1=torch.Tensor([3])
b2=torch.Tensor([1])
b3=torch.Tensor([0])
loss_1=func(a1,b1.long())
loss_2=func(a2,b2.long())
loss_3=func(a3,b3.long())
但是此时我们就会发现运行代码出错了,出错理由如下所示:
这里的意思实际上是预测值的维度和真实值的维度不匹配,我们输出一下a矩阵和拆分后的a1矩阵的大小:
a.type: torch.Size([3, 5])
a1.type: torch.Size([5])
我们会发现维度不一样,因此此时只需要把a1的维度增加一维就可以了,如下所示:
a1=torch.unsqueeze(a1,0)
a2=torch.unsqueeze(a2,0)
a3=torch.unsqueeze(a3,0)
print("loss1:",loss_1)
print("loss2:",loss_2)
print("loss3",loss_3)
loss_sum=loss_1+loss_2+loss_3
print("loss_sum",loss_sum/3)
这样输出结果为
loss1: tensor(1.6595)
loss2: tensor(1.7065)
loss3:tensor(1.6410)
loss_sum tensor(1.6690)
可以发现两种方法的结果是一样的。