pytorch优化器与学习率设置详解

简介: pytorch优化器与学习率设置详解

身为一名深度学习炼丹师,我们知道学习率对于模型训练效果来说相当重要。


然鹅,学习率过低会导致学习速度太慢,学习率过高又容易导致难以收敛。


因此,很多炼丹师都会采用动态调整学习率的方法。刚开始训练时,学习率大一点,以加快学习速度;之后逐渐减小来寻找最优解。


那么在Pytorch中,如何在训练过程里动态调整学习率呢?本文将带你深入理解优化器和学习率调整策略。


一、优化器



1. Optimizer机制


在介绍学习率调整方法之前,先带你了解一下Pytorch中的优化器Optimizer机制,模型训练时的固定搭配如下:


loss.backward()
optimizer.step()
optimizer.zero_grad()


简单来说,loss.backward()就是反向计算出各参数的梯度,然后optimizer.step()更新网络中的参数,optimizer.zero_grad()将这一轮的梯度清零,防止其影响下一轮的更新


常用优化器都在torch.optim包中,因此需要先导入包:


import torch.optim.Adamimport torch.optim.SGD


这里以Adam和SGD优化器为例,介绍一下Pytorch中的优化器使用方法。假设我们有一个网络,下面的例子都以此网络展开:


class Net(nn.Module):    
    def __init__(self):        
        super(Net, self).__init__()        
        self.layer1 = nn.Linear(10, 2)        
        self.layer2 = nn.Linear(2, 10)
    def forward(self, input):        
        return self.layer1(input)


2. Optimizer基本属性


所有Optimizer公有的一些基本属性:

  • lr: learning rate,学习率
  • eps: 学习率最小值,在动态更新学习率时,学习率最小不会小于该值。
  • weight_decay: 权值衰减。相当于对参数进行L2正则化(使模型复杂度尽可能低,防止过拟合),该值可以理解为正则化项的系数。
  • betas: (待研究)
  • amsgrad: (bool)(待研究)

每个Optimizer都维护一个param_groups的list,该list中维护需要优化的参数以及对应的属性设置。


3. Optimizer基本方法


  • add_param_group(param_group):为optimizer的param_groups增加一个参数组。这在微调预训练的网络时非常有用,因为冻结层可以训练并随着训练的进行添加到优化器中。
  • load_state_dict(state_dict):加载optimizer state。参数必须是optimizer.state_dict()返回的对象。
  • state_dict():返回一个dict,包含optimizer的状态:state和param_groups。
  • step(closure): 执行一次参数更新过程。
  • zero_grad(): 清除所有已经更新的参数的梯度。


我们在构造优化器时,最简单的方法通常如下:


model = Net()
optimizer_Adam = torch.optim.Adam(model.parameters(), lr=0.1)


model.parameters()返回模型的全部参数,并将它们传入Adam函数构造出一个Adam优化器,并设置 learning rate=0.1。


因此该 Adam 优化器的 param_groups 维护的就是模型 model 的全部参数,并且学习率为0.1,这样在调用optimizer_Adam.step()时,就会对model的全部参数进行更新。


4. param_groups


Optimizer的param_groups是一个list,其中的每个元素都是一组独立的参数,以dict的方式存储。结构如下:


-param_groups    
    -0(dict)  # 第一组参数        
        params:  # 维护要更新的参数        
        lr:  # 该组参数的学习率        
        betas:        
        eps:  # 该组参数的学习率最小值        
        weight_decay:  # 该组参数的权重衰减系数        
        amsgrad:      
    -1(dict)  # 第二组参数    
    -2(dict)  # 第三组参数    
    ...


这样可以实现很多灵活的操作,比如:


1)只训练模型的一部分参数


例如,只想训练上面的model中的layer1参数,而保持layer2的参数不动。可以如下设置Optimizer:


model = Net()
# 只传入layer层的参数,就可以只更新layer层的参数而不影响其他参数。
optimizer_Adam = torch.optim.Adam(model.layer1.parameters(), lr=0.1)


2)不同部分的参数设置不同的学习率


例如,要想使model的layer1参数学习率为0.1,layer2的参数学习率为0.2,可以如下设置Optimizer:


model = Net()
params_dict = [{'params': model.layer.parameters(), 'lr': 0.1},              
             {'params': model.layer2.parameters(), 'lr': 0.2}]
optimizer_Adam = torch.optim.Adam(params_dict)


这种方法更为灵活,手动构造一个params_dict列表来初始化Optimizer。注意,字典中的参数部分的 key 必须为‘params’


二、动态更新学习率



了解了Optimizer的基本结构和使用方法,接下来将向你介绍如何在训练过程中动态更新 learning rate。


1. 手动修改学习率


前文提到Optimizer的每一组参数维护一个lr,因此最直接的方法就是在训练过程中手动修改Optimizer中对应的lr值。


model = Net()  # 生成网络
optimizer_Adam = torch.optim.Adam(model.parameters(), lr=0.1)  # 生成优化器
for epoch in range(100):  # 假设迭代100个epoch    
    if epoch % 5 == 0:  # 每迭代5次,更新一次学习率        
        for params in optimizer_Adam.param_groups:             
            # 遍历Optimizer中的每一组参数,将该组参数的学习率 * 0.9            
            params['lr'] *= 0.9            
            # params['weight_decay'] = 0.5  # 当然也可以修改其他属性


2. torch.optim.lr_scheduler


torch.optim.lr_scheduler包中提供了一些类,用于动态修改lr。

  • torch.optim.lr_scheduler.LambdaLr
  • torch.optim.lr_scheduler.StepLR
  • torch.optim.lr_scheduler.MultiStepLR
  • torch.optim.lr_scheduler.ExponentialLR
  • torch.optim.lr_sheduler.CosineAnneaingLR
  • torch.optim.lr_scheduler.ReduceLROnPlateau

pytorch 1.1.0版本之后,在创建了lr_scheduler对象之后,会自动执行第一次lr更新(可以理解为执行一次scheduler.step())。


因此在使用的时候,需要先调用optimizer.step(),再调用scheduler.step()。

如果创建了lr_scheduler对象之后,先调用scheduler.step(),再调用optimizer.step(),则会跳过了第一个学习率的值。


# 调用顺序
loss.backward()
optimizer.step()
scheduler.step()...


具体使用方法由于篇幅有限不在此阐述了,感兴趣的伙伴可以去torch官网查看文档。


三、小结



学习率对于深度学习炼丹来说尤为重要,一个合适的学习率不仅能加速训练的拟合,还能更好地逼近最优解。


固定的学习率随着深度学习模型逐渐上升的复杂性已不太适用,动态调整学习率或者对模型不同部分设置不同的学习率已成为一种炼丹趋势。


相关文章
|
11月前
|
PyTorch Linux 算法框架/工具
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
这篇文章是关于如何使用Anaconda进行Python环境管理,包括下载、安装、配置环境变量、创建多版本Python环境、安装PyTorch以及使用Jupyter Notebook的详细指南。
1213 1
pytorch学习一:Anaconda下载、安装、配置环境变量。anaconda创建多版本python环境。安装 pytorch。
|
12月前
|
机器学习/深度学习 存储 PyTorch
PyTorch自定义学习率调度器实现指南
本文将详细介绍如何通过扩展PyTorch的 ``` LRScheduler ``` 类来实现一个具有预热阶段的余弦衰减调度器。我们将分五个关键步骤来完成这个过程。
615 2
|
机器学习/深度学习 自然语言处理 算法
【从零开始学习深度学习】49.Pytorch_NLP项目实战:文本情感分类---使用循环神经网络RNN
【从零开始学习深度学习】49.Pytorch_NLP项目实战:文本情感分类---使用循环神经网络RNN
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】43. 算法优化之Adam算法【RMSProp算法与动量法的结合】介绍及其Pytorch实现
【从零开始学习深度学习】43. 算法优化之Adam算法【RMSProp算法与动量法的结合】介绍及其Pytorch实现
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】40. 算法优化之AdaGrad算法介绍及其Pytorch实现
【从零开始学习深度学习】40. 算法优化之AdaGrad算法介绍及其Pytorch实现
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】39. 梯度下降优化之动量法介绍及其Pytorch实现
【从零开始学习深度学习】39. 梯度下降优化之动量法介绍及其Pytorch实现
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
|
12月前
|
机器学习/深度学习 PyTorch 调度
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
在深度学习中,学习率作为关键超参数对模型收敛速度和性能至关重要。传统方法采用统一学习率,但研究表明为不同层设置差异化学习率能显著提升性能。本文探讨了这一策略的理论基础及PyTorch实现方法,包括模型定义、参数分组、优化器配置及训练流程。通过示例展示了如何为ResNet18设置不同层的学习率,并介绍了渐进式解冻和层适应学习率等高级技巧,帮助研究者更好地优化模型训练。
759 4
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
|
11月前
|
机器学习/深度学习 缓存 PyTorch
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
这篇文章是关于如何下载、安装和配置Miniconda,以及如何使用Miniconda创建和管理Python环境的详细指南。
3330 0
pytorch学习一(扩展篇):miniconda下载、安装、配置环境变量。miniconda创建多版本python环境。整理常用命令(亲测ok)
|
11月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
267 1

热门文章

最新文章

推荐镜像

更多