深度学习的目标是通过不断改变网络参数,使得参数能够对输入做各种非线性变换拟合输出,本质上就是一个函数去寻找最优解,只不过这个最优解是一个矩阵,而如何快速求得这个最优解是深度学习研究的一个重点,以经典的resnet-50为例,它大约有2000万个系数需要进行计算,那么我们如何计算出这么多系数,有以下两种方法:
- 第一种是直接暴力穷举一遍参数,这种方法实施可能性基本为0,堪比愚公移山plus的难度。
- 为了使求解参数过程更快,人们提出了第二种办法,即BP+优化器逼近求解。
因此,优化器是根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值,使得模型输出更加接近真实标签。
1. Pytorch中的优化器
在pytorch中已经内置了以下的优化器:
- torch.optim.Adadelta
- torch.optim.Adagrad
- torch.optim.Adam
- torch.optim.AdamW
- torch.optim.SparseAdam
- torch.optim.Adamax
- torch.optim.ASGD
- torch.optim.LBFGS
- torch.optim.RMSprop
- torch.optim.Rprop
- torch.optim.SGD
这些优化器都继承自torch.optim.Optimizer
这个优化器的基类。
在本文中我们先介绍torch.optim.Optimizer
基类,再介绍各个优化器。
2. 优化器基类torch.optim.Optimizer
2.1 torch.optim.Optimizer
torch.optim.Optimizer(params, defaults)
torch.optim.Optimizer
为所有优化器的基类。
其中,
- params:torch.Tensors或者dict类型的可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- defaults: 一个包含优化选项默认值的字典(当参数组没有指定时使用)
2.2 torch.optim.Optimizer的属性
torch.optim.Optimizer有三个属性,
1 torch.optim.Optimizer.defaults
torch.optim.Optimizer.defaults存储的是优化器的超参数,例子如下
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim
import matplotlib.pyplot as plt
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.hidden = nn.Linear(1, 20)
self.predict = nn.Linear(20, 1)
def forward(self,x):
x = F.relu(self.hidden(x))
x = self.predict(x)
return x
if __name__ == '__main__':
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MyNet().to(device)
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001,betas=(0.9, 0.99))
print('optimizer.defaults:{}'.format(optimizer.defaults))
输出
optimizer.defaults:{'lr': 0.0001, 'betas': (0.9, 0.99), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False}
2 torch.optim.Optimizer.state
torch.optim.Optimizer.state 为参数的缓存
3. torch.optim.Optimizer.param_groups
torch.optim.Optimizer.param_groups为优化器的参数组,是一个list,然后其中每一个元素为一个字典,分别记录了params
,lr
,weight_decay
等与优化器参数相关的信息,例子如下
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim
import matplotlib.pyplot as plt
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.hidden = nn.Linear(1, 20)
self.predict = nn.Linear(20, 1)
def forward(self,x):
x = F.relu(self.hidden(x))
x = self.predict(x)
return x
if __name__ == '__main__':
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MyNet().to(device)
optimizer = torch.optim.Adam(model.parameters(),lr=0.0001,betas=(0.9, 0.99))
print('optimizer.param_groups:{}'.format(optimizer.param_groups))
输出
optimizer.param_groups:[{'params': [Parameter containing:
tensor([[-0.1789],
[-0.1629],
[-0.6816],
[-0.7967],
[-0.5432],
[-0.7973],
[-0.1869],
[ 0.7843],
[-0.1039],
[-0.4303],
[-0.4451],
[ 0.5766],
[ 0.6883],
[-0.0862],
[ 0.5169],
[ 0.0244],
[-0.1295],
[ 0.7358],
[-0.9221],
[-0.1463]], device='cuda:0', requires_grad=True), Parameter containing:
tensor([-0.3876, -0.0316, -0.1787, 0.8979, 0.9626, 0.0452, -0.8819, 0.8417,
0.7994, -0.4167, -0.1814, -0.3666, -0.6344, -0.7134, -0.3289, 0.9688,
-0.7236, -0.1622, 0.2909, 0.3827], device='cuda:0',
requires_grad=True), Parameter containing:
tensor([[ 0.2151, 0.0721, 0.1951, -0.1590, 0.0827, -0.2209, 0.1915, 0.2087,
-0.0106, -0.0042, 0.0260, -0.0419, -0.0034, 0.2065, -0.1061, 0.0834,
0.0561, -0.1628, -0.0110, 0.0828]], device='cuda:0',
requires_grad=True), Parameter containing:
tensor([0.0428], device='cuda:0', requires_grad=True)],
'lr': 0.0001,
'betas': (0.9, 0.99),
'eps': 1e-08,
'weight_decay': 0,
'amsgrad': False}]
继承自torch.optim.Optimizer
的每一个优化器都继承上述的三个属性。
2.3 torch.optim.Optimizer的方法
2.3.1 add_param_group
1. 函数形式
add_param_group(param_group)
2. 函数功能
添加一个参数组到当前优化器的参数组。
此函数在微调预训练网络时非常有用,因为可以使被冻结的层可训练并且添加到参数优化的过程中。
3. 函数参数
- param_groups:dict字典,指定应添加到参数组的Tensor
2.3.2 load_state_dict
1. 函数形式
load_state_dict(state_dict)
2. 函数功能
加载优化器状态字典。
可以用来实现模型的断点续训,继续上一次的参数进行训练。
3. 函数参数
- state_dict:dict字典,从
state_dict()
返回的优化器状态。
2.3.3 state_dict
1. 函数形式
state_dict()
2. 函数功能
返回优化器状态字典。
其返回的内容包含两个部分:
- state:当前优化状态的dict,不同的优化器保存的内容不同
- param_groups:包含所有参数组的字典
2.3.4 step
1. 函数形式
step(closure)
2. 函数功能
指定单步的优化器优化,进行参数更新。
3. 函数参数
- closure:可调用的函数对象,该函数中的功能为重新计算模型结果并返回loss。
2.3.5 zero_grad
1. 函数形式
zero_grad(set_to_none=False)
2. 函数功能
设置所有参数的梯度,将其置0。
PyTorch的特性是张量的梯度不自动清零,因此每次反向传播后都需要清空梯度。
3. 函数参数
- set_to_none:bool,默认值为False。如果设置为True时,会将梯度设置为None,而不是设置为0。这种操作通常会降低内存占用,并可一定程度提升性能,但是这种操作会影响一些方面。
比如,
1):当用户尝试访问梯度并对其执行手动操作时,None或0的张量的行为将不同;
2):如果设置为True,并进行误差反向传播,对于没有接受到梯度的参数,其梯度会一直为None;
3):对于梯度为None或者0,
torch.optim.optimizers
可能会有不同的处理方式,一种是以梯度为0进行处理,另一种则是跳过此步骤;
继承自torch.optim.Optimizer
的每一个优化器都继承上述的方法。
2.4 torch.optim.Optimizer的使用
for input, target in dataset:
# 梯度置零
optimizer.zero_grad()
# 模型推理
output = model(input)
# 求解loss
loss = loss_fn(output, target)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
或者
for input, target in dataset:
def closure():
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
return loss
optimizer.step(closure)
3. Pytorch中的优化器算法
3.1 torch.optim.Adadelta
实现论文ADADELTA: An Adaptive Learning Rate Method的算法。
1. 类形式
torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认值为1.0。在delta被应用到参数更新之前对它缩放的系数
- rho:float,默认值为0.9。用于计算平方梯度的运行平均值的系数
- eps:float,默认值为1e-6。为了增加数值计算的稳定性而加到分母里的项
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
3.2 torch.optim.Adagrad
实现论文Adaptive Subgradient Methods for Online Learning and Stochastic Optimization的算法。
1. 类形式
torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0, eps=1e-10)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
-
lr:float,默认值为1e-2。学习率
-
lr_decay:float,默认值为0。学习率衰减系数
-
weight_decay:float,默认值为0。权重衰减,L2惩罚项
-
eps:float,默认值为1e-2。为了增加数值计算的稳定性而加到分母里的项
3.3 torch.optim.Adam
实现论文[Adam: A Method for Stochastic Optimization](Adam: A Method for Stochastic Optimization)的算法,L2惩罚项的更改参考Decoupled Weight Decay Regularization。
1. 类形式
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
-
lr:float,默认为1e-3。学习率
-
betas:Tuple[float,float],默认值为[0.9,0.999]。用于计算梯度及其平方的运行平均值的系数
-
eps:float,默认值为1e-8。为了增加数值计算的稳定性而加到分母里的项
-
weight_decay:float,默认值为0。权重衰减,L2惩罚项
-
amsgrad:bool,默认值为False。是否使用本文算法的变体AMSGrad:On the Convergence of Adam and Beyond
3.4 torch.optim.AdamW
实现论文Adam: A Method for Stochastic Optimization,其变体为Decoupled Weight Decay Regularization。
1. 类形式
torch.optim.AdamW(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, amsgrad=False)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1e-3。学习率
- betas:Tuple[float,float],默认值为[0.9,0.999]。用于计算梯度及其平方的运行平均值的系数
- eps:float,默认值为1e-8。为了增加数值计算的稳定性而加到分母里的项
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
- amsgrad:bool,默认值为False。是否使用本文算法的变体AMSGrad:On the Convergence of Adam and Beyond
3.5 torch.optim.SparseAdam
实现适用于稀疏张量的Adam算法。
1. 类形式
torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1e-3。学习率
- betas:Tuple[float,float],默认值为[0.9,0.999]。用于计算梯度及其平方的运行平均值的系数
- eps:float,默认值为1e-8。为了增加数值计算的稳定性而加到分母里的项
3.6 torch.optim.Adamax
实现Adamax算法(基于无穷范数的Adam变体),在论文Adam: A Method for Stochastic Optimization提出。
1. 类形式
torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为2e-3。学习率
- betas:Tuple[float,float],默认值为[0.9,0.999]。用于计算梯度及其平方的运行平均值的系数
- eps:float,默认值为1e-8。为了增加数值计算的稳定性而加到分母里的项
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
3.7 torch.optim.ASGD
实现论文Acceleration of stochastic approximation by averaging中提出的平均梯度下降算法。
1. 类形式
torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1e-2。学习率
- lambd:float,默认为1e-4。衰减项
- alpha:float,默认值为0.75。eta更新力度
- t0:float,默认值为1e6。开始求平均值的点
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
3.8 torch.optim.LBFGS
实现L-BFGS算法
1. 类形式
torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-07, tolerance_change=1e-09, history_size=100, line_search_fn=None)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1。学习率
- max_iter:int,默认值为20。每个优化步骤的最大迭代次数
- max_eval:int,默认值为max_iter * 1.25。每个优化步骤的最大函数评估数
- tolerance_grad:float,默认值为1e-5。一阶最优性的终止容差
- tolerance_change:float,默认值为1e-9。功能值/参数变化的终止容差
- history_size:int,默认值为100。更新历史记录大小
- line_search_fn:str,默认值为None。strong_wolft或者None
3.9 torch.optim.RMSprop
实现RMSprop算法。
1. 类形式
torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1e2。学习率
- momentum:float,默认值为0。动量因子
- alpha:float,默认值为0.99。平滑常数
- eps:float,默认值为1e-8。为了增加数值计算的稳定性而加到分母里的项
- centered:bool,默认值为False。如果设置为True,计算中心RMSProp,通过估计其方差对梯度进行归一化
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
3.10 torch.optim.Rprop
实现弹性反向传播算法
1. 类形式
torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float,默认为1e2。学习率
- etas:Tuple[float,float],默认值为(0.5,1.2)。(etamius,etaplis)数据对,乘法递增因子和递减因子
- step_sizes:Tuple[float,float],默认值为(1e-6,50),最小和最大允许步长
3.11 torch.optim.SGD
实现随机梯度下降算法(可选动量)
1. 类形式
torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)
2. 类参数
- params:可迭代对象,一般是指torch.nn.Module.paramters(),即网络的参数
- lr:float。学习率
- momentum:float,默认值为0。动量因子
- dampening:float,默认值为0。动量阻尼
- weight_decay:float,默认值为0。权重衰减,L2惩罚项
- nesterov:bool,默认为False。如果设置为True,则启用Nesterov momentum
参考链接
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:Pytorch – torch.optim优化器
原文链接:https://www.stubbornhuang.com/2228/
发布于:2022年08月03日 8:55:29
修改于:2023年06月25日 20:47:51
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
52