学习率范围测试
本教程展示了如何在 PyTorch 中执行学习率范围测试。
学习率范围测试 (LRRT)
学习率范围测试(LRRT)是一种用于发现可在训练模型时使用而不会发散的最大学习率值的方法。数据科学家通常对这些信息感兴趣,因为与较小的学习率相比,较大的学习率会导致模型更快地收敛。此外,较大的学习率对于诸如CLR 和1Cycle 之类的学习率调度至关重要,这些调度用于有效地使用大批量大小进行训练。DeepSpeed 为 PyTorch 框架中的模型训练提供 LRRT。
先决条件
要使用 DeepSpeed 的 LRRT,您必须满足以下两个条件
- 使用入门指南将 DeepSpeed 集成到您的训练脚本中。
- 将配置 LRRT 的参数添加到模型的参数中。LRRT 参数定义如下。
LRRT 参数
LRRT 通过以预定义的量以预定义的间隔线性增加学习率来工作。因此,LRRT 是一种学习率调度形式,因为它定义了在模型训练期间学习率如何以及何时应该改变。要配置 LRRT,您需要设置这些参数
lr_range_test_min_lr
:训练的初始学习率(float)
lr_range_test_step_size
:按训练步骤定义的学习率向上缩放的间隔(integer)
lr_range_test_step_rate
:增加学习率的缩放因子(float)
lr_range_test_staircase
:如果为真,则学习率每lr_range_test_step_size
训练步骤更改一次,否则学习率在每个训练步骤更改一次(boolean)
所需的模型配置更改
我们将说明所需的模型配置更改和一个示例 LRRT 调度,该调度
- 从 0.0001 的初始学习率开始训练
- 使用 5 的缩放率
- 使用 200 个训练步骤的缩放间隔
- 在每个训练步骤缩放学习率,即不使用阶梯
PyTorch
对于 PyTorch 模型,LRRT 作为学习率调度器实现,这是 PyTorch 1.0.1 及更高版本中提供的功能。因此,您可以将类型为 "LRRangeTest"
的 "scheduler"
条目添加到您的模型配置中,如下所示
"scheduler": {
"type": "LRRangeTest",
"params": {
"lr_range_test_min_lr": 0.0001,
"lr_range_test_step_size": 200,
"lr_range_test_step_rate": 5,
"lr_range_test_staircase": false
}
}
示例:调整大批量大小
我们通过我们调整内部生产模型以在更大的批量大小上有效收敛的经验片段来说明 LRRT 如何使数据科学家受益,因为我们从一个 GPU(批量大小为 512)扩展到四个 GPU(批量大小为 2048)。我们的目标是使用更大的批量大小训练模型,以使用相同数量的数据样本匹配较小批量大小的性能。这里的挑战是大批量大小训练的众所周知的缓慢收敛问题。我们的方法是在 DeepSpeed 中使用1Cycle 调度来解决此问题,并且我们使用 LRRT 来配置调度。
在下图中,我们说明了使用 LRRT 发现有效训练批量大小为 2048 的最大学习率。左侧的图显示了大学习率对训练前 9000 个批次的验证损失的影响。右侧的图显示了训练期间的学习率值。使用网格搜索,我们发现批量大小为 2048 的最佳固定学习率为 0.0002。蓝线(lr=0.0002
)表示使用此固定学习率进行训练。我们将两个 LRRT 调度与该固定学习率进行比较。橙色(lr_range_test_step_rate=5
)和灰色(lr_range_test_step_rate=50
)线条分别表示使用仅在 lr_range_test_step_rate
值方面不同的类似 LRRT 调度进行训练。尽管 LRRT 调度从相同的基学习率开始,但灰色线条的学习率增长速度比橙色线条快约 10 倍。此外,LRRT 调度的学习率已超过在所示数据点中蓝线的学习率。随后,我们分别将灰色线称为“快速增长”和橙色线称为“缓慢增长”LRRT 调度。
我们从这个小例子中得出以下观察结果。
-
较大的学习率显然有利于模型性能,直至某个点。快速增长的 LRRT 调度在 3000 个批次后达到 0.46 的验证损失,而固定学习率在 9000 个批次内无法达到。缓慢增长的 LRRT 直到 6000 个批次后才达到该分数,但它保持着优于固定学习率的性能优势。
-
学习率值存在一个上限,这些值对训练模型有用。快速增长的 LRRT 调度很快就会达到此边界并发散,而缓慢增长的 LRRT 稍后也会因相同原因发散。LRRT 帮助我们快速发现了这些边界,使用了不到 2% 的训练数据。这些边界对于构建学习率调度很有用信息。
来自 LRRT 的这些观察结果帮助我们配置了学习率边界和用于解决问题的 1Cycle 调度的周期跨度,如下所示。
"OneCycle": {
"cycle_min_lr": 0.002,
"cycle_max_lr": 0.005,
"cycle_first_step_size": 2000,
"cycle_second_step_size": 2000,
...
}
根据我们的经验,以下是 1Cycle 调度的四个最关键的参数。
- 我们选择使用较慢的 LRRT 调度(
lr_range_test_step_rate=5
)来设置cycle_min_lr
,因为它实现了最佳损失,并且更快的调度会相当快地发散。 - 我们将
cycle_min_lr
设置为 0.005,即使图表显示性能在略高的学习率下仍在提高。这是因为我们观察到,如果我们等到最大学习率,模型可能处于发散点,并且无法恢复。 - 由于学习率变为 0.005 需要 8000 个批次,因此我们将
cycle_first_step_size
和(cycle_second_step_size
)设置为 2000,这是四个 GPU 处理 8000 个批次所需的步数。
我们希望这个简短的示例能够激发您使用 LRRT 解决您自己独特的调整挑战的想象力。