自己从头实现了一个神经网络 但是在运行的时候发现问题:训练loss从第二个epoch开始震荡(震荡幅度还挺大的)不下降
训练和验证集损失如下图所示
很长时间觉得是自己的模型拟合能力不足 找了非常多的原因和解决办法
最后发现是一个很小的点自己写错了(很不容易找到的bug):
我在模型训练的时候使用了学习率下降策略,但没有正确使用它
以下是我的错误代码
# 定义优化器和学习率下降策略
optim = torch.optim.Adam(params, lr=learning_rate, betas=(0.5, 0.999))
scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size=30, gamma=0.1)
# train
for epoch in range(epoches):
model.train()
for step, sample in enumerate(train_loader):
output = model(input)
optim.zero_grad()
loss = loss_function(output, label)
loss.backward()
optim.step()
scheduler.step()
...
注意这里将scheduler.step()
放在了每个epoch的内循环里面!!!!!!
这样会导致每次取出sample计算loss之后都执行一次学习率下降 导致一个epoch之后学习率就已经下降到非常低了!!模型从第二个epoch开始就不会学到任何东西了!!!
正确的操作应该是:
# train
for epoch in range(epoches):
model.train()
for step, sample in enumerate(train_loader):
output = model(input)
optim.zero_grad()
loss = loss_function(output, label)
loss.backward()
optim.step()
scheduler.step()
scheduler.step()
应该在每个 epoch 全部算完之后做
改过这里之后loss正常下降了
这件事情提醒自己:一旦对lr或者其他的东西做了改动 一定要print出来 代码一定要规范 就像下面一样
模型学习过程中变动的值一定要打印出来检查一下