最近在训练一个分类类网络的时候,发现损失不收敛,网络的各个部分没有问题,输入输出都是正常的情况,但就是网络的损失不收敛,最开始的交叉熵损失在6左右,一直到50个epoch以后,损失依然是5左右,map 和rank1都很扎心。
后来分析后发现,最后的分类网络送出来的各个值都太小了,使得经过softmax后的各个类别的概率差异不大,为了解决这个问题,在将分类网络送出的结果,在送入交叉熵损失函数之前,加一个temperature就可以了。
1.下面的代码是不收敛的一个伪代码,分类网络送出来以后,直接送入了交叉熵损失函数,结果不收敛
prob = self.classifier(x)
loss = self.crossentropyloss(prob,label)
2.下面的代码是收敛的,分类网路送出来以后,将这个输出除以一个温度系数,可以调节softmax输出的差异性,相当于是让softmax的分布更锐化一些
prob = self.classifier(x)
prob = prob / self.temp
loss = self.crossentropyloss(prob,label)
我将temp设置为0.1,具体是多少,可以自行设定
对于通用的计算交叉熵的公式如下:
但是对于0-1分布的交叉熵计算公式则可以简化为如下:
刚开始的时候不理解为什么这么改动,以为蕴含着什么深层次的概念和技巧了,其实很简单,0-1分布就是二分类,可以将二分类问题看作是有两种类别的分类问题,知道了一个事件概率p,则另一个事件的概率为1-p,因此预测的一个类别的概率为q,则另一个事件的概率应该为1-q。因此改动成上面的计算公式也就是顺理成章了。