之前訓練網絡時,會先編寫學習率隨訓練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;
- 排查順序:
- 訓練數據(包括label)中有無異常值(nan, inf等);
- 網絡中有無除法,確保分母不會出現0, 分母可以加一個eps=1e-8;
- 網絡中有無開根號(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),反之,學習率對應調小