解决交叉熵损失不收敛的问题

637 阅读1分钟

 

最近在训练一个分类类网络的时候,发现损失不收敛,网络的各个部分没有问题,输入输出都是正常的情况,但就是网络的损失不收敛,最开始的交叉熵损失在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,具体是多少,可以自行设定

​ ​

 

在训练网络的时候,发现输出全都是nan,这个时候很大可能是数值不稳定,比如除数太小,不稳定,或者是log里面的参数太小,不稳定,这个时候在可能出现运算不稳定的地方增加一些稳定系数就好了,比如:

1.在分母的位置增加一个稳定数

exp_st_sum = exp_st_with_target.sum(dim=1, keepdim=True) + 1e-6
exp_st_rate = exp_st_with_target / exp_st_sum
    

2.在log里增加稳定系数

loss_gt = F.nll_loss(torch.log(exp_gt_rate + 1e-6), labels)

这样就能解决出现的问题了

​上述的两个问题是长在训练中会出现的情况,按照这种方式解决了也就好了