我正在尝试重新实施一篇论文,该论文建议如下调整学习率:
学习率降低了回归值的一个因数,其中耐心时间为0.0001的变化值为。
我应该使用torch.optim.lr_scheduler.ReduceLROnPlateau()
吗?
我不确定应该为每个参数传递什么值。
语句中的更改值是否表示参数阈值?
语句中的 factor 是否表示参数 factor ?
答案 0 :(得分:3)
Pytorch有许多方法可以让您降低学习速度。在这里有很好的解释:
https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate
@Antonino DiMaggio很好地解释了ReduceOnPlateau。我只想补充答案以回复@ Yan-JenHuang的评论:
是否可以将学习率降低一个恒定值而不是一个因子?
首先,您应该非常小心,以免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
答案 1 :(得分:2)
torch.optim.lr_scheduler.ReduceLROnPlateau
确实是您想要的。我为您总结了所有重要内容。
mode=min
:当监视的数量停止减少时,lr将减少
factor
:学习率降低的因素
patience
:没有改善的时期数,之后学习率将降低
threshold
:衡量新的最佳阈值,仅关注重大变化(变化值)。假设我们有threshold=0.0001
,如果在纪元 n 上的损失为18.0,在纪元 n + 1 上的损失为17.9999,那么我们已经满足了乘以当前学习的条件按factor
进行评分。
criterion = torch.nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min',
factor=0.1, patience=10, threshold=0.0001, threshold_mode='abs')
for epoch in range(20):
# training loop stuff
loss = criterion(...)
scheduler.step(loss)
您可以在文档中查看更多详细信息:https://pytorch.org/docs/stable/optim.html#torch.optim.lr_scheduler.ReduceLROnPlateau
答案 2 :(得分:1)
作为上述ReduceLROnPlateau答案的补充,pytorch的lr调度程序中的阈值也有modes(rel|abs)(至少对于vesions>=1.6),默认为'rel',这意味着如果你的损失是18,它至少会改变18*0.0001=0.0018才能被认为是一种改进。所以,也要注意阈值模式。