🍨 本文为🔗365天深度学习训练营中的学习记录博客
- 🍖 原作者:K同学啊
一、我的环境
二、动态学习率
这个地方使用的是官方的动态学习率接口,最开始源代码中0.92 ** (epoch // 2),在多轮实验中,后期的模型都训练不动,loss不降我采用了Adam、标签平滑、正则化,都没有讲test_acc提升到84%。掉回头来修改衰减梯度,在最后两轮达到了最终目标,修改代码是0.95*epoch,减缓了衰减速度,让模型更容易收敛。我也不懂为啥就实现了目标,我问ai,ai建议如下。最近建议我尝试余弦退火策略,因为我的acc曲线最终还是掉了一些下去,
为什么“平滑”能提高准确率?
你可以看看这两个对比图(想象):
配合动量(Momentum):
现在的优化器(如 Adam)都有“惯性”。
旧方案的突变会打断惯性,导致模型在那个瞬间方向迷失。
新方案顺应惯性,让模型在减速的同时依然保持方向感,更容易滑入“全局最优解”(Global Minima)。
更早的干预:
旧方案前 2 轮学习率完全没变。如果初始学习率这就有点大,前 2 轮可能已经跑偏了。
新方案从第 1 轮就开始减速(乘以 0.95)。这种“尽早介入、温柔介入”的策略,能防止模型在训练初期因为步子太大而跳出最优解的坑。
三 代码
# # 调用官方动态学习率接口时使用 learn_rate = 1e-4 lambda1 = lambda epoch: (0.95 ** epoch) optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate) scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) #选定调整方法loss_fn = nn.CrossEntropyLoss() # 创建损失函数 epochs = 40 train_loss = [] train_acc = [] test_loss = [] test_acc = [] for epoch in range(epochs): # 更新学习率(使用自定义学习率时使用) model.train() epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer) # scheduler.step() # 更新学习率(调用官方动态学习率接口时使用) model.eval() epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn) scheduler.step() train_acc.append(epoch_train_acc) train_loss.append(epoch_train_loss) test_acc.append(epoch_test_acc) test_loss.append(epoch_test_loss) # 获取当前的学习率 lr = optimizer.state_dict()['param_groups'][0]['lr'] template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}') print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss, lr)) print('Done')