我现在使用SGD optimizer训练Faster R-CNN时,初始学习率1e-3则收敛效果很好,如果设置成1e-2则loss会出现NAN的情况。
而在使用Adam optimizer时,使用initial learning rate=1e-3和1e-4都会导致loss在epoch=1时出现NAN的情况,
故而想到之前的计算cross entropy分类损失所使用的trick,loss函数值NAN可能是由于分类损失函数所导致的,
classification loss中的输入往往是直接经过convolution operation或者fc nn.Linear操作输出的数值,
并没有经历过任何激活函数的操作,这是因为pytorch 中的torch.nn.functional.softmax函数中本来就包含了如下步骤:
(1)先对input/prediction计算softmax,然后取log值,
(2)计算prediction与target之间的nll loss(non-log likelihood loss)。
它认为经历过softmax函数后的数值可以表示概率含义,但是如果属于正确类别的概率预测值很小,则log之后将会出现极大的负数,
故而加上概率平滑项1e-3,认为在不附加上网络模型输出的任何预测值之前,先认为当前样本属于每个类别的概率值都初始化为1e-3。
import torch
import numpy as np
import torch.nn.functional as F
prediction=torch.randn((5,10))
target=np.random.randint(0,9,(5))
target=torch.from_numpy(target).long()
loss1=F.cross_entropy(prediction,target,reduction='elementwise_mean')
print('loss1',loss1)
loss2=F.nll_loss(F.log_softmax(prediction,1),target,reduction='elementwise_mean')
print('loss2',loss2)
loss3=F.nll_loss(torch.log(F.softmax(prediction,1)),target,reduction='elementwise_mean')
print('loss3',loss3)
loss4=F.nll_loss(torch.log(F.softmax(prediction,1)+1e-3),target,reduction='elementwise_mean')
print('loss4',loss4)
'''
loss = F.nll_loss(torch.log(F.softmax(input, dim=1) + 1e-3), target, weight=weights, reduction='elementwise_mean')
loss1 tensor(1.9831)
loss2 tensor(1.9831)
loss3 tensor(1.9831)
loss4 tensor(1.9756)
'''
pytorch cross entropy training trick
最新推荐文章于 2022-06-28 17:14:55 发布