Pytorch框架之优化器 Optimizer

基本用法

  • 优化器主要是在模型训练阶段对模型可学习参数进行更新, 常用优化器有 SGDRMSpropAdam
  • 优化器初始化时传入传入模型的可学习参数,以及其他超参数如 lrmomentum
  • 在训练过程中先调用 optimizer.zero_grad() 清空梯度,再调用 loss.backward() 反向传播,最后调用 optimizer.step()更新模型参数

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

  • add_param_group(param_group): 添加模型可学习参数组
  • step(closure): 进行一次参数更新
  • zero_grad(): 清空上次迭代记录的梯度信息
  • state_dict(): 返回 dict 结构的参数状态
  • load_state_dict(state_dict): 加载 dict 结构的参数状态
class Optimizer(object):def __init__(self, params, defaults):# 初始化优化器只需要将模型的可学习参数(params)和超参数(defaults)分别传入优化器的构造函数,下面是Optimizer的初始化函数核心代码:torch._C._log_api_usage_once("python.optimizer")# # 字典类型,子类传入,用于表示全部参数组的默认超参self.defaults = defaultsself._hook_for_profile()if isinstance(params, torch.Tensor):raise TypeError("params argument given to the optimizer should be ""an iterable of Tensors or dicts, but got " +torch.typename(params))self.state = defaultdict(dict)self.param_groups = []param_groups = list(params)if len(param_groups) == 0:raise ValueError("optimizer got an empty parameter list")if not isinstance(param_groups[0], dict):param_groups = [{'params': param_groups}]for param_group in param_groups:self.add_param_group(param_group)def state_dict(self):# Save order indices instead of Tensorsparam_mappings = {}start_index = 0def pack_group(group):nonlocal start_indexpacked = {k: v for k, v in group.items() if k != 'params'}param_mappings.update({id(p): i for i, p in enumerate(group['params'], start_index)if id(p) not in param_mappings})packed['params'] = [param_mappings[id(p)] for p in group['params']]start_index += len(packed['params'])return packedparam_groups = [pack_group(g) for g in self.param_groups]# Remap state to use order indices as keyspacked_state = {(param_mappings[id(k)] if isinstance(k, torch.Tensor) else k): vfor k, v in self.state.items()}return {'state': packed_state,'param_groups': param_groups,}def load_state_dict(self, state_dict):# deepcopy, to be consistent with module APIstate_dict = deepcopy(state_dict)# Validate the state_dictgroups = self.param_groupssaved_groups = state_dict['param_groups']if len(groups) != len(saved_groups):raise ValueError("loaded state dict has a different number of ""parameter groups")param_lens = (len(g['params']) for g in groups)saved_lens = (len(g['params']) for g in saved_groups)if any(p_len != s_len for p_len, s_len in zip(param_lens, saved_lens)):raise ValueError("loaded state dict contains a parameter group ""that doesn't match the size of optimizer's group")# Update the stateid_map = {old_id: p for old_id, p inzip(chain.from_iterable((g['params'] for g in saved_groups)),chain.from_iterable((g['params'] for g in groups)))}def cast(param, value):r"""Make a deep copy of value, casting all tensors to device of param."""if isinstance(value, torch.Tensor):# Floating-point types are a bit special here. They are the only ones# that are assumed to always match the type of params.if param.is_floating_point():value = value.to(param.dtype)value = value.to(param.device)return valueelif isinstance(value, dict):return {k: cast(param, v) for k, v in value.items()}elif isinstance(value, container_abcs.Iterable):return type(value)(cast(param, v) for v in value)else:return valuestate = defaultdict(dict)for k, v in state_dict['state'].items():if k in id_map:param = id_map[k]state[param] = cast(param, v)else:state[k] = v# Update parameter groups, setting their 'params' valuedef update_group(group, new_group):new_group['params'] = group['params']return new_groupparam_groups = [update_group(g, ng) for g, ng in zip(groups, saved_groups)]self.__setstate__({'state': state, 'param_groups': param_groups})def zero_grad(self, set_to_none: bool = False):#在反向传播计算梯度之前对上一次迭代时记录的梯度清零,参数`set_to_none` 设置为 True 时会直接将参数梯度设置为 None,从而减小内存使用, 但通常情况下不建议设置这个参数,因为梯度设置为 None 和 0 在 PyTorch 中处理逻辑会不一样。if not hasattr(self, "_zero_grad_profile_name"):self._hook_for_profile()with torch.autograd.profiler.record_function(self._zero_grad_profile_name):for group in self.param_groups:for p in group['params']:if p.grad is not None:if set_to_none:p.grad = Noneelse:if p.grad.grad_fn is not None:p.grad.detach_()else:p.grad.requires_grad_(False)p.grad.zero_()def step(self, closure):# 基类 Optimizer 定义了 step 方法接口,raise NotImplementedErrordef add_param_group(self, param_group):# 该方法在初始化函数中用到,主要用来向 self.param_groups添加不同分组的模型参数assert isinstance(param_group, dict), "param group must be a dict"params = param_group['params']if isinstance(params, torch.Tensor):param_group['params'] = [params]elif isinstance(params, set):raise TypeError('optimizer parameters need to be organized in ordered collections, but ''the ordering of tensors in sets will change between runs. Please use a list instead.')else:param_group['params'] = list(params)for param in param_group['params']:if not isinstance(param, torch.Tensor):raise TypeError("optimizer can only optimize Tensors, ""but one of the params is " + torch.typename(param))if not param.is_leaf:raise ValueError("can't optimize a non-leaf Tensor")for name, default in self.defaults.items():if default is required and name not in param_group:raise ValueError("parameter group didn't specify a value of required optimization parameter " +name)else:param_group.setdefault(name, default)params = param_group['params']if len(params) != len(set(params)):warnings.warn("optimizer contains a parameter group with duplicate parameters; ""in future, this will cause an error; ""see github.com/pytorch/pytorch/issues/40967 for more information", stacklevel=3)param_set = set()for group in self.param_groups:param_set.update(set(group['params']))if not param_set.isdisjoint(set(param_group['params'])):raise ValueError("some parameters appear in more than one parameter group")self.param_groups.append(param_group)

简单使用示例如下所示:

import torch
import numpy as np
import warningswarnings.filterwarnings('ignore') #ignore warnings
x = torch.linspace(-np.pi, np.pi, 2000)
y = torch.sin(x)
p = torch.tensor([1, 2, 3])
xx = x.unsqueeze(-1).pow(p)
model = torch.nn.Sequential(
torch.nn.Linear(3, 1),
torch.nn.Flatten(0, 1)
)
loss_fn = torch.nn.MSELoss(reduction='sum')
learning_rate = 1e-3
optimizer = torch.optim.RMSprop(model.parameters(), lr=learning_rate)
for t in range(1, 1001):y_pred = model(xx)loss = loss_fn(y_pred, y)if t % 100 == 0:print('No.{: 5d}, loss: {:.6f}'.format(t, loss.item()))optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算梯度optimizer.step() # 梯度下降法更新参数

PyTorch 中的优化器

所有优化器都是继承父类 Optimizer,如下列表是 PyTorch 提供的优化器:
SGD
ASGD
Adadelta
Adagrad
Adam
AdamW
Adamax
SparseAdam
RMSprop
Rprop
LBFGS

分成学习率优化

利用 add_param_group 函数功能,可以对模型不同的可学习参数组设定不同的超参数,初始化优化器可传入元素是 dictlist,每个 dict 中的 keyparams或者其他超参数的名字如lr,下面是一个实用的例子:对模型的fc层参数设置不同的学习率

from torch.optim import SGD
from torch import nn
class DummyModel(nn.Module):
def __init__(self, class_num=10):
super(DummyModel, self).__init__()
self.base = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(64, 128, kernel_size=3, padding=1),
nn.ReLU(),
)
self.gap = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Linear(128, class_num)
def forward(self, x):
x = self.base(x)
x = self.gap(x)
x = x.view(x.shape[0], -1)
x = self.fc(x)
return x
model = DummyModel().cuda()
optimizer = SGD([
{'params': model.base.parameters()},
{'params': model.fc.parameters(), 'lr': 1e-3} # 对 fc的参数设置不同的学习率
], lr=1e-2, momentum=0.9)

Pytorch框架之优化器 Optimizer相关推荐

  1. 一文详解Pytorch中的优化器Optimizer

    本文将结合源码与代码示例详细解析Optimizer的五大方法. 1. 前言 优化器主要用在模型训练阶段,用于更新模型中可学习的参数.torch.optim提供了多种优化器接口,比如Adam.RAdam ...

  2. Pytorch优化器Optimizer

    优化器Optimizer 什么是优化器 pytorch的优化器:管理并更新模型中可学习参数的值,使得模型输出更接近真实标签 导数:函数在指定坐标轴上的变化率 方向导数:指定方向上的变化率(二元及以上函 ...

  3. 【PyTorch基础教程9】优化器optimizer和训练过程

    学习总结 (1)每个优化器都是一个类,一定要进行实例化才能使用,比如: class Net(nn.Moddule):··· net = Net() optim = torch.optim.SGD(ne ...

  4. Pyotrch —— 优化器Optimizer(一)

    目录 1.什么是优化器 2.optimizer的属性 3.optimizer的方法 4.代码分析 5.优化器基本方法的使用 1.什么是优化器 Pytorch优化器:管理并更新模型中可学习参数的值,使得 ...

  5. pytorch adagrad_【学习笔记】Pytorch深度学习—优化器(二)

    点击文末 阅读原文,体验感更好哦! 前面学习过了Pytorch中优化器optimizer的基本属性和方法,优化器optimizer的主要功能是 "管理模型中的可学习参数,并利用参数的梯度gr ...

  6. pytorch学习十 ---- 优化器

    1.什么是优化器? 首先我们回忆一下机器学习的五大模块:数据.模型.损失函数.优化器.迭代训练 在损失函数中我们会得到一个loss值,即真实标签与预测标签的差异值,对于loss我们通常会采用pytor ...

  7. PyTorch基础-Adam优化器使用-06

    当不知道使用什么优化器的时候可以使用adam优化器 代码 import numpy as np import torch from torch import nn,optim from torch.a ...

  8. mysql cbo优化器_Oracle的优化器(Optimizer) (CBO优化) 分享

    Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行 计划去执行.分析语句的执行计划的工作是由优化器(Optimiz Oracle的优化器(Optimizer) (CBO优化) ...

  9. 优化器 optimizer

    优化器 optimizer optimizer 优化器,用来根据参数的梯度进行沿梯度下降方向进行调整模型参数,使得模型loss不断降低,达到全局最低,通过不断微调模型参数,使得模型从训练数据中学习进行 ...

最新文章

  1. 测试驱动开发与行为驱动开发中的测试先行方法
  2. 桐城中学2021高考成绩查询,桐城中学2019高考成绩喜报、一本二本上线情况
  3. WebForm中关于DataGrid的20篇经典文章
  4. Codeforces 458C - Elections
  5. python3 tensorflowprint错误_解决import tensorflow as tf 出错的原因
  6. 在c语言中log函数的作用,C++_在C语言中使用对数函数的方法,C语言log()函数:返回以e为底的 - phpStudy...
  7. Caffe: Faster-RCNN Python版本配置 (Windows)
  8. [转帖]Docker save and load镜像保存
  9. mysql xp系统时间_【Mysql5.5 XP系统下载】mysql XP系统安装图解
  10. 组合分类和回归的神经网络模型
  11. BZOJ4872: [Shoi2017]分手是祝愿
  12. CodeSmith 7.01破解
  13. ABC互联 shopex网店主机 试用
  14. linux du 查看文件夹大小
  15. 用计算机说出人说的话,用计算机语言说一句情话
  16. win10安装kafka kafka_2.13-2.8.1
  17. 系统工程--011详细设计 伪码 程序流程图 PAD图 N-S图 判断表和判断树
  18. LT01 创建转储单
  19. 高级计算机培训 英语教案设计,第四课时英语教案设计
  20. 为了彻底搞清楚数据库 E-R 模型设计,我肝了这篇万字长文

热门文章

  1. 钢之炼金术师之第三季片尾曲铃声 钢之炼金术师之第三季片尾曲...
  2. 初学spring aop 注解遇到的问题
  3. IT男频繁猝死背后的心理探秘
  4. Cocos Creator 预制体(Prefab) - 生命周期详解
  5. JS为什么是单线程?
  6. iOS app安全技术总结
  7. 特殊权限(附加权限)
  8. 火猴浏览器3.0的语义解析突破
  9. android.intent.action.view 融云,使用融云SDK遇到的一些问题
  10. 大巴车载15KW静音汽油发电机检修和保养