PyTorch ReduceLROnPlateau调度器异常降LR问题排查
问题排查:ReduceLROnPlateau在验证精度持续上升时仍降低学习率
我用PyTorch训练MobileNetV3Large模型,配置了ReduceLROnPlateau学习率调度器,但发现验证精度持续上升的情况下,调度器还是降低了学习率。以下是训练代码片段和前7轮训练日志,帮忙排查原因:
训练代码
bench_val_loss = 1000 bench_acc = 0.0 epochs = 15 optimizer = optim.Adam(embeddingNet.parameters(), lr=1e-3) loss_optimizer = torch.optim.Adam(loss_fn.parameters(), lr=1e-3) scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=3, threshold=0.02) for epoch in range(1, epochs + 1): print(f'current lr: {scheduler.get_last_lr()}') loss=train(embeddingNet, loss_fn, device, train_dataloader, optimizer, loss_optimizer, epoch) val_loss, accuracy =test(train_dataset, val_dataset, embeddingNet, accuracy_calculator, loss_fn, epoch, val_dataloader) #val_loss = simpleTest(train_dataset, val_dataset, embeddingNet, accuracy_calculator, loss_fn, epoch, val_dataloader) torch.save(embeddingNet.state_dict(), 'my/path/mobileNetV3L_ArcFaceLAST.pth') if accuracy >= bench_acc: bench_val_loss = val_loss torch.save(embeddingNet.state_dict(), 'my/path/mobileNetV3L_ArcFaceBEST.pth') scheduler.step(accuracy) writer.add_scalars('Training vs. Validation Loss', {'Training': loss, 'Validation': val_loss}, global_step=epoch+1)
前7轮训练日志
Test set accuracy (Precision@1) = 0.17834772304046048 current lr: [0.001] Epoch 3: Loss = 39.68284225463867 Epoch 3: valLoss = 39.9765007019043 100%|██████████| 962/962 [01:43<00:00, 9.28it/s] 100%|██████████| 370/370 [00:41<00:00, 8.92it/s] Computing accuracy Test set accuracy (Precision@1) = 0.31242593533096324 current lr: [0.001] Epoch 4: Loss = 39.4412841796875 Epoch 4: valLoss = 39.67761562450512 100%|██████████| 962/962 [01:45<00:00, 9.11it/s] 100%|██████████| 370/370 [00:41<00:00, 8.86it/s] Computing accuracy Test set accuracy (Precision@1) = 0.3633824276282377 current lr: [0.001] Epoch 5: Loss = 39.09823989868164 Epoch 5: valLoss = 39.54649614901156 100%|██████████| 962/962 [01:42<00:00, 9.37it/s] 100%|██████████| 370/370 [00:41<00:00, 8.87it/s] Computing accuracy Test set accuracy (Precision@1) = 0.44244117149145085 current lr: [0.001] Epoch 6: Loss = 38.70449447631836 Epoch 6: valLoss = 39.1865906792718 100%|██████████| 962/962 [01:45<00:00, 9.15it/s] 100%|██████████| 370/370 [00:39<00:00, 9.25it/s] Computing accuracy Test set accuracy (Precision@1) = 0.5167597765363129 current lr: [0.0001]
问题分析与修复
核心错误
调度器的配置和传入的监控指标不匹配:
- 你设置了
scheduler = ReduceLROnPlateau(..., mode='min'),这个模式表示调度器会监控指标的下降,当指标连续patience轮没有下降(即没有改善)时降低学习率。 - 但你调用
scheduler.step(accuracy)时传入的是精度,这是一个需要最大化的指标——精度持续上升对mode='min'的调度器来说,相当于指标一直在"没有改善"(因为它在等指标变小),所以触发了学习率下降逻辑。
两种修复方式
- 调整调度器的mode参数:因为监控的是精度(需要最大化),将
mode改为'max':
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.1, patience=3, threshold=0.02)
- 切换监控指标为验证损失:如果你想保留
mode='min',就把scheduler.step(accuracy)改成scheduler.step(val_loss)——验证损失是需要最小化的指标,和mode='min'逻辑匹配。
额外注意
你的代码中使用了两个独立的Adam优化器(optimizer用于模型参数,loss_optimizer用于损失函数参数),但当前调度器只绑定了optimizer,如果loss_fn包含可训练参数,loss_optimizer的学习率不会被调度,若需要统一调度,需为其也配置对应的学习率调度器。
内容的提问来源于stack exchange,提问作者elbarto
相关产品推荐
相关产品推荐

