Pytorch 有很多方法可以让你降低学习率。这里解释得很好:
https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate
@Antonino DiMaggio 很好地解释了 ReduceOnPlateau。我只是想补充一下回复@Yan-JenHuang的评论:
是否可以通过减去一个常数值而不是一个因子来降低 learning_rate?
首先,你应该非常小心避免 lr 的负值!其次,减去学习率的值不是常见的做法。但无论如何……
你得先做一个自定义的lr调度器(我修改了LambdaLR的代码https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html#LambdaLR):
torch.optim.lr_scheduler import _LRScheduler
class SubtractLR(_LRScheduler):
def __init__(self, optimizer, lr_lambda, last_epoch=-1, min_lr=e-6):
self.optimizer = optimizer
self.min_lr = min_lr # min learning rate > 0
if not isinstance(lr_lambda, list) and not isinstance(lr_lambda, tuple):
self.lr_lambdas = [lr_lambda] * len(optimizer.param_groups)
else:
if len(lr_lambda) != len(optimizer.param_groups):
raise ValueError("Expected {} lr_lambdas, but got {}".format(
len(optimizer.param_groups), len(lr_lambda)))
self.lr_lambdas = list(lr_lambda)
self.last_epoch = last_epoch
super(LambdaLR, self).__init__(optimizer, last_epoch)
def get_lr(self):
if not self._get_lr_called_within_step:
warnings.warn("To get the last learning rate computed by the scheduler, "
"please use `get_last_lr()`.")
return [(max(base_lr - lmbda(self.last_epoch), self.min_lr)
for lmbda, base_lr in zip(self.lr_lambdas, self.base_lrs)] # reduces the learning rate
你可以在训练中使用它。
lambda1 = lambda epoch: e-4 # constant to subtract from lr
scheduler = SubtractLR(optimizer, lr_lambda=[lambda1])
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
lambda1 = lambda epoch: epoch * e-6 # increases the value to subtract lr proportionally to the epoch
scheduler = SubtractLR(optimizer, lr_lambda=[lambda1])
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
你也可以修改ReduceLROnPlateau的代码来减去学习率而不是相乘。您应该将这一行 new_lr = max(old_lr * self.factor, self.min_lrs[i]) 更改为 new_lr = max(old_lr - self.factor, self.min_lrs[i])。可以自己看代码:https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html#ReduceLROnPlateau