关于loss不收敛的一些建议

之前训练网络时,会先编写学习率随训练epoch的增加而逐渐减低的函数,然后选取一个相对较大的学习率(一般从e-2量级开始),选取一个epoch能够接受的batchsize,如果loss稳定下降较快,则开始训练.从未体验过学习率和batchsize搭配之难.

最近新看了一篇论文ABCNN(有空再细讲),采用开源的tensorflow工程训练一下,效果很好,因工程需要,开始将其移植到pytorch框架下,移植完毕后,关于loss函数遇到不少问题,在此记录.

1.学习率随epoch降低的函数

def adjust_learning_rate(learning_rate, learning_rate_decay, optimizer, epoch):
    """Sets the learning rate to the initial LR multiplied by learning_rate_decay(set 0.98, usually) every epoch"""
    learning_rate = learning_rate * (learning_rate_decay ** epoch)

    for param_group in optimizer.param_groups:
        param_group['lr'] = learning_rate

    return learning_rate

2.loss变nan

  • 现象:loss进行一次反传后,loss变nan;
  • 排查顺序:
    1. 训练数据(包括label)中有无异常值(nan, inf等);
    2. 网络中有无除法,确保分母不会出现0, 分母可以加一个eps=1e-8;
    3. 网络中有无开根号(torch.sqrt), 保证根号下>=0, 我的程序即是由此引起的(未保证不出现0或者极小正值的情况),解决也是加一个eps=1e-8.

3.loss不收敛

此处包含两种情况,一种是loss一直在震荡,一种是loss下降一点后不再下降到理想水平,而验证集上的表现保持不变.

1.保持需要的batchsize不变;
2.查看是否有梯度回传,查看代码如下:

for name, parms in model.named_parameters():
	print('-->name:', name, '-->grad_requirs:', parms.requires_grad, '--weight', torch.mean(parms.data), ' -->grad_value:', torch.mean(parms.grad))

3.查看数据是否有问题,如标签错乱等现象;
4.调节学习率,从大向小调,建议每次除以5;我的项目即是因为学习率过大过小都不收敛引起的;
5.如果学习率调好后,需要调节batchsize大小,如batchsize调大2倍,则将学习率对应调大(项目测试调大2~3倍OK),反之,学习率对应调小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章