在使用MIML的过程中,我需要对属于同一标签中的子概念进行损失值计算,采用的是nn.CrossEntropyLoss()交叉熵损失函数,然而我就出现上述这种情况,于是我自己写了一个小小的示例进行问题解决:
首先对正确的示例进行介绍:
import torch.nn as nnimport torchfunc=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_3print(\"loss_sum\",loss_sum/3)
这样输出结果为
loss1: tensor(1.6595)loss2: tensor(1.7065)loss3:tensor(1.6410)loss_sum tensor(1.6690)
可以发现两种方法的结果是一样的。