Pytorch:torch.optim模块
信息来源:网络    时间:2024-03-11 12:35

本篇笔记主要介绍torch.optim模块,记录学习过程

在深度学习中,我们通常会使用优化算法来调整神经网络的权重和偏差,以便模型能够更好地拟合训练数据。是PyTorch中的一个模块,它提供了各种优化算法的实现,用于自动化地优化神经网络的参数。换句话说,可以帮助我们让模型更好地学习,从而提高性能。

简单使用示例如下所示:

 

1.1 PyTorch 中的优化器

所有优化器都是继承父类 Optimizer,如下列表是 PyTorch 提供的优化器:
(具体用法和优缺点,后续更新。。。。。。。。。。。)

1.2 父类Optimizer 基本原理

Optimizer 是所有优化器的父类,它主要有如下公共方法:

: 添加模型可学习参数组
: 进行一次参数更新
: 清空上次迭代记录的梯度信息
: 返回 dict 结构的参数状态
: 加载 dict 结构的参数状态

上述方法一一解读:

1.2.1 初始化 Optimizer

初始化优化器只需要将模型的**可学习参数(params)超参数(defaults)**分别传入优化器的构造函数

关键几个点为:

  1. self.defaults = defaults
  2. self.state = defaultdict(dict)
  3. self.param_groups = [] 特别重要,最需要记住的属性,特别是属性的内容和其形式。
  4. self.add_param_group方法,往self.param_groups里面放东西。

下面是Optimizer的初始化函数核心代码:

 

该初始化方法接收两个参数,一个是params,一个是defaults

这两个分开说,先说params,最常见的就是model.parameters(),当然net.parameters()也是一样的,就是模型类的对象的变量名不同,如下所示。

 

params是个生成器,只返回各模型层的参数,没有参数名。

注意__init__方法中,得到一个新的变量 ,(这里self.param_groups是干什么的呢??)。

,list可以把生成器的元素都取出来,所以,很明显,param_groups就是一个Parameter类对象的列表,里面的元素是每个网络层的参数weight和bias(如果有)

 

param_groups[0]是Parameter类,不是dict,这种形式的param_groups会被改造,将整个param_groups作为值,"params"作为键,形成一个键值对,放在字典里,然后重新赋值给param_groups。

现在我们要记得 的形式,一个列表,里面是一个字典,字典的键是"params",值为所有网络层的参数。

 

将param_groups中的每个元素送进这个列表中。现在的param_groups里只有一个元素{“param”: [参数]}。

1.2.2 add_param_group

该方法在初始化函数中用到,主要用来向 添加不同分组的模型参数

 

将上述代码分为8个步骤: 请认真看一遍代码以及注释

现在我们知道self.param_groups这个列表中具有字典,每个字典的keys为dict_keys([‘params’, ‘lr’, ‘momentum’, ‘dampening’, ‘weight_decay’, ‘nesterov’]),当然,每个键都有其对应的值。这些键值对是构建SGD实例时,传进来的参数。

params还有一种常见形式如下。

 

我们可以对比一下 这种形式(前面讲的)上述model.parameters() 这种方式的不同。

1.2.3 step

此方法主要完成一次模型参数的更新

基类 Optimizer 定义了 step 方法接口,如下所示

 

子类如 SGD 需要实现 step 方法,如下所示:

 
 

下面是 closure 的简单示例:

 
1.2.4 zero_grad

在反向传播计算梯度之前对上一次迭代时记录的梯度清零,参数set_to_none 设置为 True 时会直接将参数梯度设置为 None,从而减小内存使用

但通常情况下不建议设置这个参数,因为梯度设置为 None 和 0 在 PyTorch 中处理逻辑会不一样。

 
1.2.5 state_dict() 和 load_state_dict

这两个方法实现序列化反序列化功能。

两个方法可用来实现模型训练中断后继续训练功能

 
 

2.1 基类: _LRScheduler

学习率调整类主要的逻辑功能就是每个 epoch 计算参数组的学习率,更新 optimizer对应参数组中的lr值,从而应用在optimizer里可学习参数的梯度更新。

所有的学习率调整策略类的父类是,基类 定义了如下方法:

2.1.1 初始化

LR_scheduler是用于调节学习率lr的,在代码中,我们经常看到这样的一行代码

 

在pytorch代码中,各种类型scheduler大多基于 _LRScheduler

基类的初始化函数可传入两个参数,

此时会对optimizer里的各参数组设置初始学习率 initial_lr。若last_epoch传入值大于 -1,则代表从某个 epoch 开始继续上次训练,此时要求optimizer的参数组中有initial_lr初始学习率信息。

初始化函数内部的 函数主要是为了确保是在之后调用的 (PyTorch=1.1 发生变化). 注意在__init__函数最后一步调用了self.step(),即_LRScheduler在初始化时已经调用过一次step()方法。

 
2.1.2 step

当模型完成一个 epoch 训练时,需要调用step()方法,该方法里对last_epoch自增之后,在内部上下文管理器类里调用子类实现的get_lr()方法获得各参数组在此次 epoch 时的学习率,并更新到 optimizer的param_groups属性之中,最后记录下最后一次调整的学习率到self._last_lr,此属性将在get_last_lr()方法中返回。在这个方法中用到了上下文管理功能的内部类 _enable_get_lr_call,实例对象添加了_get_lr_called_within_step属性,这个属性可在子类中使用。此外,需要注意的是,step方法中的参数epoch已经废弃了,在使用时可以直接忽略这个参数。

 
2.1.3 get_last_lr、get_lr和print_lr

get_last_lr()方法比较简单,就是step()方法调用后,记录的最后一次 optimizer各参数组里更新后的学习率信息
get_lr() 方法是抽象方法,定义了更新学习率策略的接口,不同子类继承后会有不同的实现.其返回值是[lr1, lr2, …]结构
print_lr(is_verbose, group, lr, epoch=None)): 该方法提供了显示 lr 调整信息的功能

 
2.1.4 state_dict 和 load_state_dict

这两个方法和Optimizer里的方法功能是一样的,就是为了保存和重新加载状态信息,需要注意的是,这里不会重复记录self.optimizer属性的状态信息,因为 Optimizer 有自己实现的对应方法。

state_dict(): 以字典 dict 形式返回当前实例除 self.optimizer 之外的其他所有属性信息
load_state_dict(state_dict): 重新载入之前保存的状态信息

 

参考:
https://zhuanlan.zhihu.com/p/346205754?utm_medium=social&utm_oi=73844937195520&utm_id=0
https://zhuanlan.zhihu.com/p/539642125

| 首页 | 关于顺盈娱乐 | 顺盈新闻 | 顺盈注册 | 顺盈登录 | 顺盈平台 | 顺盈代理 | 顺盈APP下载 |

ICP备案:粤IP******** Copyright © 2002-2022 顺盈平台官方指定注册站 版权所有

平台注册入口