eecn/Hyperspectral-Classification

为什么optim.lr_scheduler.ReduceLROnPlateau的step中使用“metric = -val_acc”?

Pancakerr opened this issue · 7 comments

if val_loader is not None:
val_acc = val(net, val_loader, device=device, supervision=supervision)
val_accuracies.append(val_acc)
metric = -val_acc
else:
metric = avg_loss

    if isinstance(scheduler, optim.lr_scheduler.ReduceLROnPlateau):
        scheduler.step(metric)

感谢您的代码,在阅读过程中我对models.py train函数中的 scheduler设置部分有疑问,想请教一下,pytorch官网中示例给出ReduceLROnPlateau的step使用“val_loss”,为何这里用“metric = -val_acc“?望解惑,谢谢!

optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = ReduceLROnPlateau(optimizer, 'min')
for epoch in range(10):
train(...)
val_loss = validate(...)
# Note that step should be called after validate()
scheduler.step(val_loss)

eecn commented

抱歉,一直没关注issues。
我认为是因为这里的metric是分类准确率,我们是要最大化分类准确率。而在分类loss中一般交叉熵都是在最小化loss。

eecn commented

在构建 ReduceLROnPlateau对象时,参数mode默认使用了"min"参数。

In min mode, lr will be reduced when the quantity monitored has stopped decreasing.ReduceLROnPlateau

即当监测的数量停止减少时,lr将减少;
针对val_acc增加时,我们希望学习率降低以减轻梯度振荡。
这里进行backward使用CE loss我觉得更合理。使用准确率进行反向传播只有正确的样本的梯度对网络的训练有贡献,一般都难以有效收敛。

感谢答疑,看代码的时候我也觉得用loss不再下降来调整lr可能会更好。我对pytorch中scheduler的用法不是很清楚,你在上个回答中说“使用准确率进行反向传播”,是说scheduler.step()同时做了lr调整和optimizer.step()吗?scheduler.step()本身有optimizer.step()功能吗?

eecn commented

讨论的是loss的设计,跟学习率的衰减策略无关。scheduler只负责学习率的衰减策略,optimizer则是优化方法。
说的有点远了。我是想表达分类问题不使用交叉熵等loss直接使用我们关注的准确率作为loss的劣势。
之前跟人讨论过为什么不用模型评价指标作为训练loss进行模型训练。
不过这个代码里面只是使用val_acc作为学习率的衰减观测量,我认为是合理的。

您好,兄弟你知道为什么这个框架在validation阶段不开model.eval()吗?有dropout,有BN层为什么只在推理阶段使用model.eval()呀?实在是stuck了好久,是他错了还是我理解出错了呢?

您好,兄弟你知道为什么这个框架在validation阶段不开model.eval()吗?有dropout,有BN层为什么只在推理阶段使用model.eval()呀?实在是stuck了好久,是他错了还是我理解出错了呢?

原则上应该加.eval()的,可能是作者的疏忽,我在自己的代码里加上了

好嘞,多谢hxd