机器学习
回归模型评估
案例一:鸢尾花分类
机器学习的优化算法
交叉熵
lightGBM
处理非平衡数据集的方法
AdaBoost
GBDT
XGBoost
决策树
线性回归
pytorch 优化器的使用
分类模型评估
损失函数
前馈神经网络
特征工程
分箱
评分卡实现过程
逻辑回归
本文档使用 MrDoc 发布
-
+
首页
pytorch 优化器的使用
在使用pytorch训练模型时,经常会有以下步骤: ```python model = MyModel() criterion = nn.CrossEntropyLoss() # 初始化optimizer,将模型的参数传递过去 optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-4) for epoch in range(1, epochs): for i, (inputs, labels) in enumerate(train_loader): output= model(inputs) # 1. 计算损失函数 loss = criterion(output, labels) # 2. 清零梯度 optimizer.zero_grad() # 3. 损失函数计算梯度 loss.backward() # 4. 使用梯度下降更新模型参数 optimizer.step() ``` 其中有三个重要的函数调用: - `optimizer.zero_grad()` 将梯度清零; - `loss.backward()` 通过反向传播计算每个特征的梯度; - `optimizer.step()` 通过梯度下降方法来更新模型参数; 一些比较重要的参数: - `param_groups: List[Dict]`Optimizer 类在实例化时会初始化一个`param_groups`参数,该参数是一个列表,列表中的元素是字典类型; - `param_group["params"]`由传入的`模型参数`(即特征属性对应的`weight`)组成的列表,即实例化Optimizer类时传入该group的参数,如果参数没有分组,则为整个模型的参数model.parameters(),每个参数是一个`torch.nn.parameter.Parameter`对象,该对象包含了`梯度属性grad`用于记录每个参数的梯度值。 > **问题**:有个很奇怪的问题,`optimizer.step()`难道不需要loss和model作为参数吗,它是怎么获取到梯度信息,又是怎么更新模型参数的? > **简答**:其实在初始化`optimizer`的时候就已经将模型的参数传递给它,所以它持有所有的模型参数,而梯度信息也是模型参数的属性; > **问题**:通过`loss.backward()`反向传播可以计算梯度,但是我们知道梯度值是存在于模型参数里面的,那么loss是如何更新模型参数的梯度属性呢? > **简答**:其实是因为`output`有一个`grad_fn`属性,该属性是一个回调函数,通过该属性可以修改模型参数的梯度属性`grad`; 接下来我们通过源码来理解这三个函数。 `1. optimizer.zero_grad()` 梯度值清零 ```python class Optimizer(object): def zero_grad(self): """Clears the gradients of all optimized :class:`torch.Tensor` s.""" for group in self.param_groups: # 遍历所有模型参数,清零他们的梯度 for p in group["params"]: if p.grad is not None: p.grad.detach_() p.grad.zero_() ``` 该方法会遍历所有的参数,并执行以下步骤: - 通过`p.grad.detach_()`方法截断反向传播的梯度流,其实就是移除`grad_fn`属性; - 再通过`p.grad.zero_()`方法将每个参数的梯度值设为0,即清除上一次的梯度值; `2. loss.backward()` 反向传播计算梯度。但是我们知道梯度值是存在于模型参数里面的,那么`loss`是如何更新模型参数的梯度属性呢? 其实是因为`output`有一个`grad_fn`属性,该属性是一个回调函数,通过该属性可以修改模型参数的梯度属性`grad`; `3. optimizer.step()` ```python class Optimizer(object): def step(self, closure=None): """Performs a single optimization step""" loss = None if closure is not None: loss = closure() for group in self.param_groups: weight_decay = group['weight_decay'] momentum = group['momentum'] dampening = group['dampening'] nesterov = group['nesterov'] # 遍历模型参数,根据各参数的梯度更新它们的值 for p in group['params']: if p.grad is None: continue d_p = p.grad.data if weight_decay != 0: d_p.add_(weight_decay, p.data) if momentum != 0: #此处省略 pass p.data.add_(-group['lr'], d_p) return loss ``` ### 参考 > [pytorch中文文档:torch.optim](https://ptorch.com/docs/1/optim) > [理解optimizer 的作用及原理](https://blog.csdn.net/PanYHHH/article/details/107361827) > [Stackoverflow: pytorch - connection between loss.backward() and optimizer.step()](https://stackoverflow.com/questions/53975717/pytorch-connection-between-loss-backward-and-optimizer-step) > [Github: Pytorch 源码](https://github.com/pytorch/pytorch/blob/master/torch/optim/optimizer.py) > [Autograd看这一篇就够了!](https://blog.csdn.net/qq_43328040/article/details/108421469)
gaojian
2022年11月22日 13:37
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码