optimzer | cabbage

cabbage

菜鸟写给小白的教程

0%

optimzer

optimzer

传统的训练函数,一个batch是这么训练的:

  1. 获取loss:输入图像和标签,通过infer计算得到预测值,计算损失函数;
  2. optimizer.zero_grad() 清空过往梯度;
  3. loss.backward() 反向传播,计算当前梯度;
  4. optimizer.step() 根据梯度更新网络参数

一、optimizer的基本参数
defaults:优化器超参数
state:参数的缓存,如momentum的缓存
param_groups:管理的参数组
_step_count:记录更新次数,学习率调整中使用(比如要在第n次迭代后降低学习率)

二、optimizer的基本使用方法
zero_grad():清空所有参数的梯度,因为张量不会自动清零会自动累加,在梯度求导之前需要进行梯度清零
step():进行一步更新
add_param_groups():添加一组参数
state_dict():获取优化器当前状态信息字典
load_state_dict():加载状态信息字典
————————————————
https://blog.csdn.net/m0_55769743/article/details/122717287

https://blog.csdn.net/m0_37628604/article/details/121630836
四个函数作用是先将梯度值归零(optimizer.zero_grad()),然后反向传播计算每个参数的梯度值(loss.backward()),通过梯度下降进行参数更新(optimizer.step()),最后根据opeoch训练轮数更新学习率(lr_scheduler.step())。

接下来通过源码对四个函数进行分析。在此之前说明函数中常见的参数变量。
param_groups:Optimizer类在实例化时会创建一个param_groups列表,列表中有num_groups(num_groups取决于你定义optimizer时传入了几组参数)个长度为6的param_group字典,每个param_group包含了[‘param’,‘lr’,‘momentum’,‘dampening’,‘weight_decay’,‘nesterov’]这6组键值对。
params(iterable)—待优化参数w、b 或者定义了参数组的dict
lr(float,可选)—学习率
momentum(float,可选,默认0)—动量因子
weight_decay(float,可选,默认0)—权重衰减
dampening (float, 可选) – 动量的抑制因子(默认:0)
nesterov (bool, 可选) – 使用Nesterov动量(默认:False)
param_group[‘param’]:由传入的模型参数组成的列表,即实例化Optimizer类时传入该group的参数,如果参数没有分组,则为整个模型的参数model.parameters(),每个参数是一个torch.nn.parameter.Parameter对象。

https://blog.csdn.net/qq_40379132/article/details/124573071 -仔细看看

https://blog.csdn.net/weixin_43863869/article/details/128120719

梯度累计

简单的说就是进来一个batch的数据,计算一次梯度,更新一次网络
使用梯度累加是这么写的
获取loss:输入图像和标签,通过infer计算得到预测值,计算损失函数;
loss.backward() 反向传播,计算当前梯度;
多次循环步骤1-2,不清空梯度,使梯度累加在已有梯度上;
梯度累加了一定次数后,先optimizer.step() 根据累计的梯度更新网络参数,然后optimizer.zero_grad() 清空过往梯度,为下一波梯度累加做准备;

一定条件下,batchsize越大训练效果越好,梯度累加则实现了batchsize的变相扩大,如果accumulation_steps为8,则batchsize ‘变相’ 扩大了8倍,是我们这种乞丐实验室解决显存受限的一个不错的trick,使用时需要注意,学习率也要适当放大。

对模型参数的梯度置0时通常使用两种方式:model.zero_grad()optimizer.zero_grad()。二者在训练代码都很常见,那么二者的区别在哪里呢?

https://www.cnblogs.com/chaofengya/p/16925125.html
转自 https://cloud.tencent.com/developer/article/1710864

使用

https://blog.csdn.net/lishanlu136/article/details/121284421

auto.grad

https://blog.csdn.net/qq_39208832/article/details/117415229

torch.Tensor 是这个包的核心类。如果设置它的属性 .requires_gradTrue,那么它将会追踪对于该张量的所有操作。当完成计算后可以通过调用 .backward(),来自动计算所有的梯度。这个张量的所有梯度将会自动累加到.grad属性.

要阻止一个张量被跟踪历史,可以调用 .detach() 方法将其与计算历史分离,并阻止它未来的计算记录被跟踪。为了防止跟踪历史记录(和使用内存),可以将代码块包装在 with torch.no_grad(): 中。在评估模型时特别有用,因为模型可能具有 requires_grad = True 的可训练的参数,但是我们不需要在此过程中对他们进行梯度计算。