如何使用OneCycleLR?

Cas*_*aJr 3 optimization neural-network deep-learning pytorch learning-rate

我想在 CIFAR-10 上进行训练,假设训练 200 个时期。\n这是我的优化器:\n optimizer = optim.Adam([x for x in model.parameters() if x.requires_grad], lr=0.001)\n我想使用 OneCycleLR 作为调度程序。现在,根据文档,这些是 OneCycleLR 的参数:

\n
torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr, total_steps=None, epochs=None, steps_per_epoch=None, pct_start=0.3, anneal_strategy='cos', cycle_momentum=True, base_momentum=0.85, max_momentum=0.95, div_factor=25.0, final_div_factor=10000.0, three_phase=False, last_epoch=- 1, verbose=False)\n
Run Code Online (Sandbox Code Playgroud)\n

我发现最常用的是max_lr,epochssteps_per_epoch。文档是这样说的:

\n
    \n
  • max_lr(浮点或列表)\xe2\x80\x93 每个参数组循环中的学习率上限。
  • \n
  • epochs (int) \xe2\x80\x93 要训练的纪元数。如果未提供total_steps 的值,则将其与steps_per_epoch 一起使用,以便推断循环中的总步数。默认值:无
  • \n
  • steps_per_epoch (int) \xe2\x80\x93 每个时期训练的步数。如果未提供total_steps 的值,则将其与epoch 一起使用,以便推断循环中的总步数。默认值:无
  • \n
\n

关于steps_per_epoch,我在许多github repo中看到它被使用steps_per_epoch=len(data_loader),所以如果我的批量大小为128,那么这个参数它等于128。\n但是我不明白其他2个参数是什么。如果我想训练 200 个 epoch,那么epochs=200?或者这是一个仅运行调度程序epoch然后重新启动的参数?例如,如果我在调度器内部写epochs=10,但我总共训练了200,那么就像调度器的20个完整步骤?\n然后max_lr我看到有人使用大于优化器lr的值,还有其他人使用较小的值。我认为它max_lr必须大于 lr (否则为什么它被称为 max :smiley: ?)\n但是,如果我逐个纪元打印学习率纪元,它会假设奇怪的值。例如,在此设置中:

\n
optimizer = optim.Adam([x for x in model.parameters() if x.requires_grad], lr=0.001)\n\nscheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr = 0.01, epochs=200, steps_per_epoch=128)\n
Run Code Online (Sandbox Code Playgroud)\n

这是学习率:

\n
Epoch 1: TrL=1.7557, TrA=0.3846, VL=1.4136, VA=0.4917, TeL=1.4266, TeA=0.4852, LR=0.0004,\nEpoch 2: TrL=1.3414, TrA=0.5123, VL=1.2347, VA=0.5615, TeL=1.2231, TeA=0.5614, LR=0.0004,\n...\nEpoch 118: TrL=0.0972, TrA=0.9655, VL=0.8445, VA=0.8161, TeL=0.8764, TeA=0.8081, LR=0.0005,\nEpoch 119: TrL=0.0939, TrA=0.9677, VL=0.8443, VA=0.8166, TeL=0.9094, TeA=0.8128, LR=0.0005,\n
Run Code Online (Sandbox Code Playgroud)\n

所以lr在增加

\n

w56*_*68w 5

文档说你应该给出total_steps或两者epochs & steps_per_epoch作为参数。他们之间的简单关系是total_steps = epochs * steps_per_epoch

total_steps循环中的总步数。OneCycle名称中的意思是训练只有一个周期。

max_lr是 的最大学习率OneCycleLR。确切地说,学习率在第一步中会从max_lr / div_factor到逐渐增加,然后平滑下降。max_lrpct_start * total_stepsmax_lr / final_div_factor


编辑:对于那些不熟悉的人lr_scheduler,您可以绘制学习率曲线,例如

EPOCHS = 10
BATCHES = 10
steps = []
lrs = []
model = ... # Your model instance
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9) # Wrapped optimizer
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer,max_lr=0.9,total_steps=EPOCHS * BATCHES)
for epoch in range(EPOCHS):
    for batch in range(BATCHES):
        scheduler.step()
        lrs.append(scheduler.get_last_lr()[0])
        steps.append(epoch * BATCHES + batch)

plt.figure()
plt.legend()
plt.plot(steps, lrs, label='OneCycle')
plt.show()
Run Code Online (Sandbox Code Playgroud)