首先我们需要知道的是:优化器的作用是什么捏??
它是一个实现各种优化算法的包。 大部分常用的方法都已经支持,接口也足够通用,以后也可以轻松集成更复杂的方法。
优化器主要是在模型训练阶段对模型可学习参数进行更新, 常用优化器有 SGD,RMSprop,Adam等。优化器初始化时传入传入模型的可学习参数,以及其他超参数如 lr
,momentum
等。在训练过程中先调用 optimizer.zero_grad()
清空梯度,再调用 loss.backward()
反向传播,最后调用 optimizer.step()
更新模型参数
它的作用是根据反向传播算法更新神经网络中的参数,以达到降低损失值loss的目的
torch.optim只用于参数更新和对参数的梯度置0,不能计算参数的梯度,在使用torch.optim进行参数更新之前,需要写前向与反向传播求导的代码。
Optimizer
是所有优化器的父类,它主要有如下公共方法:
add_param_group(param_group): 添加模型可学习参数组
step(closure): 进行一次参数更新
zero_grad(): 清空上次迭代记录的梯度信息
state_dict(): 返回 dict 结构的参数状态
load_state_dict(state_dict): 加载 dict 结构的参数状态
所有优化器都是继承父类 Optimizer
,如下列表是 PyTorch 提供的优化器:
SGD
ASGD
Adadelta
Adagrad
Adam
AdamW
Adamax
SparseAdam
RMSprop
Rprop
LBFGS
自行实现计算变量的梯度再进行更新梯度的代码:
import torch
from torch.autograd import Variable
# 定义参数w
w = Variable(torch.FloatTensor([1,2,3]),requires_grad = True)
# 定义输出
shuChu = torch.mean(w)
# 反向求导
shuChu.backward()
lr = 0.001
# 手动进行参数的更新
w.data.zero_() # 求导更新参数之前需先设置导数为0
w.data.sub_(lr*w.grad.data) # 学习率乘上w的值
使用torch.optim实现更新梯度
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
# 定义了一个网络
steps = 6
# 定义optim对象
optimizer = optim.SGD(net.parameters(), lr = 0.01)
# 循环中更新参数
for i in range(steps):
optimizer.zero_grad() # 网络参数的导数变化为0
output = net(input) # 网络前向计算
loss = criterion(output, target) # 计算损失
loss.backward() # 得到模型中参数对当前输入的梯度,使用损失的值后面加上.backward()反向传播
optimizer.step() # 保存更新的参数
如何进行使用torch.optim
要使用 torch.optim,需要构造一个优化器对象,该对象将保存当前状态并根据计算出的梯度更新参数。构建它要构造一个优化器,你必须给它一个包含要优化的参数(都应该是 Variable)的迭代。 然后,您可以指定特定于优化器的选项,例如学习率、权重衰减等。如果需要通过 .cuda() 将模型移动到 GPU,请在为其构建优化器之前执行此操作。 .cuda() 之后的模型参数将是与调用之前不同的对象。通常,在构建和使用优化器时,应该确保优化的参数位于一致的位置。
代码示例:
optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.3) # model.parameters()的意思是模型的全部参数 lr是学习率 momentum是初始化的一个动量
optimizer = optim.Adam([val_1, var_2], lr=0.01)
Optimizer还支持指定每个参数选项
只需传递一个可迭代的dict来替换先前可迭代的Variable。dict中的每一项都可以定义为一个单独的参数组,参数组用一个params键来包含属于它的参数列表。其他键应该与优化器接受的关键字参数相匹配,才能用作此组的优化选项。
optim.ASGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 1e-6}
], lr=1e-1, momentum=0.3)
如上,model.base.parameters()将使用1e-6的学习率,model.classifier.parameters()将使用1e-1的学习率。0.3的momentum作用于所有的parameters(这个模型的全部参数)。