学习率范围测试的Pythorch实现
torch-lr-finder的Python项目详细描述
Pythorch学习率查找器
Leslie N.Smith在Cyclical Learning Rates for Training Neural Networks中详细介绍了学习速率范围测试的PyTorch实现,以及fastai使用的调整版本。在
学习率范围测试是一种提供关于最佳学习率的有价值信息的测试。在训练前的训练过程中,学习率在两个边界之间呈线性或指数增长。较低的初始学习率使网络开始收敛,随着学习率的提高,最终会变得过大,网络将发散。在
通常,良好的静态学习率可以在下降损失曲线的一半找到。在下面的图中是lr = 0.002
。在
对于学习率在两个边界之间循环的周期性学习率(在Leslie Smith的论文中也有详细说明),作者分别建议了损失开始下降的点和损失停止下降或变得参差不齐的点。在下面的图中,start_lr = 0.0002
和end_lr=0.2
。在
安装
Python 3.5及以上版本:
pip install torch-lr-finder
在混合精度训练的支持下安装(另请参见this section):
^{pr2}$实施细节和用途
来自fastai
以指数方式增加学习率,并计算每个学习率的训练损失。lr_finder.plot()
绘制了训练损失与对数学习率的关系图。在
fromtorch_lr_finderimportLRFindermodel=...criterion=nn.CrossEntropyLoss()optimizer=optim.Adam(model.parameters(),lr=1e-7,weight_decay=1e-2)lr_finder=LRFinder(model,optimizer,criterion,device="cuda")lr_finder.range_test(trainloader,end_lr=100,num_iter=100)lr_finder.plot()# to inspect the loss-learning rate graphlr_finder.reset()# to reset the model and optimizer to their initial state
莱斯利·史密斯的方法
线性增加学习率并计算每个学习率的评估损失。lr_finder.plot()
绘制评估损失与学习率的关系图。
这种方法通常会生成更精确的曲线,因为求值损失更容易出现偏差,但执行测试需要更长的时间,尤其是在求值数据集很大的情况下。在
fromtorch_lr_finderimportLRFindermodel=...criterion=nn.CrossEntropyLoss()optimizer=optim.Adam(model.parameters(),lr=0.1,weight_decay=1e-2)lr_finder=LRFinder(model,optimizer,criterion,device="cuda")lr_finder.range_test(trainloader,val_loader=val_loader,end_lr=1,num_iter=100,step_mode="linear")lr_finder.plot(log_lr=False)lr_finder.reset()
注释
- CIFAR10和MNIST的示例可以在Examples文件夹中找到。在
- 传递给
LRFinder
的优化器不应附加LRScheduler
。在 LRFinder.range_test()
将更改模型权重和优化器参数。两者都可以用LRFinder.reset()
恢复到初始状态。在- 学习率和损失历史可以通过
lr_finder.history
访问。这将返回一个带有lr
和loss
键的字典。在 - 当使用
step_mode="linear"
时,学习率范围应在相同的数量级内。在 LRFinder.range_test()
期望从传递给它的DataLoader
对象返回一对{}。 input
必须准备好传递给模型,label
必须准备好传递给criterion
,而无需任何进一步的数据处理/处理/转换。如果您发现自己需要一个变通方法,您可以使用类TrainDataLoaderIter
和{}来执行 DataLoader
和训练/评估循环之间的任何数据处理/处理/转换。您可以在examples/lrfinder_cifar10_dataloader_iter中找到如何使用这些类的示例。在
额外的培训支持
梯度累积
您可以在LRFinder.range_test()
中设置accumulation_steps
参数,以执行渐变累积:
fromtorch.utils.dataimportDataLoaderfromtorch_lr_finderimportLRFinderdesired_batch_size,real_batch_size=32,4accumulation_steps=desired_batch_size//real_batch_sizedataset=...# Beware of the `batch_size` used by `DataLoader`trainloader=DataLoader(dataset,batch_size=real_batch_size,shuffle=True)model=...criterion=...optimizer=...# (Optional) With this setting, `amp.scale_loss()` will be adopted automatically.# model, optimizer = amp.initialize(model, optimizer, opt_level='O1')lr_finder=LRFinder(model,optimizer,criterion,device="cuda")lr_finder.range_test(trainloader,end_lr=10,num_iter=100,step_mode="exp",accumulation_steps=accumulation_steps)lr_finder.plot()lr_finder.reset()
混合精度训练
目前,我们使用^{LRFinder
之前调用amp.initialize()
。e、 g
fromtorch_lr_finderimportLRFinderfromapeximportamp# Add this line before running `LRFinder`model,optimizer=amp.initialize(model,optimizer,opt_level='O1')lr_finder=LRFinder(model,optimizer,criterion,device='cuda')lr_finder.range_test(trainloader,end_lr=10,num_iter=100,step_mode='exp')lr_finder.plot()lr_finder.reset()
注意,混合精度训练的好处是需要一个带有张量核心的nvidia GPU(另请参见:NVIDIA/apex #297)
另外,可以尝试设置torch.backends.cudnn.benchmark = True
来提高训练速度。(但在某些情况下它是行不通的,你应该自担风险使用它)
贡献和拉动请求
欢迎所有贡献,但首先,请看一下CONTRIBUTING.md。在
- 项目
标签: