pytorch 优化器

pytorch优化器:管理并更新模型中可学习参数的值,使模型输出更接近标签。

梯度下降策略

导数:导数在指定坐标轴上的变化率

方向导数:指定方向上的变化率

梯度:方向导数取得最大的方向,一个向量,模长为方向导数的长度

优化器

    def __init__(self, params, defaults):
        torch._C._log_api_usage_once("python.optimizer")
        self.defaults = defaults
        #: {'lr': 0.01, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}
        
        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 = []  #list

        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)  #添加参数![]
paramter_group.PNG
paramter_list_2.PNG

基本属性

default:优化器的超参数

state:参数的缓存

params_groups:管理的参数组,list类型,每一个元素是一个字典,‘params’:'values'

_step_count:记录更新的次数

optimizer.PNG
'''
1.优化器的作用是管理并更新参数组,请构建一个SGD优化器,通过add_param_group方法添加三组参数,
三组参数的学习率分别为 0.01, 0.02, 0.03, momentum分别为0.9, 0.8, 0.7,构建好之后,
并打印优化器中的param_groups属性中的每一个元素的key和value(提示:param_groups是list,其每一个元素是一个字典)
'''
flag = 0
# flag = 1
if flag:
    lr_list = [0.01, 0.02, 0.03]

    momentum_list = [0.9, 0.8, 0.7]

    x = torch.tensor([2.], requires_grad=True)
    optimizer = optim.SGD([x],lr=0.01,momentum=0.9)
    #构造一个SGD优化器

    for i,lr in enumerate(lr_list):
        w2 = torch.randn((1), requires_grad=True)
        para_dic = {'params':w2, 'lr':lr, 'momentum':momentum_list[i]}
        optimizer.add_param_group(para_dic)
    for i,para in enumerate(optimizer.param_groups):
        print("optimizer.param_groups {} is\n{}".format(i,para))

基本方法

1.zero_grad():清空所有管理参数的梯度,pytorch不会自动清零梯度,在进行求梯度之前就要清零

2.step():执行一步更新,有很多方法,动量法什么的

3.add_param_group():添加参数组到优化器中,参数可以分组,对不同的参数组,可以有不同的权值、学习率

4.state_dict():获取优化器当前状态信息字典,也保存

5.load_state_dict():加载状态信息字典

state_dict before step:
 {'state': {}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [2187292089544]}]}
state_dict after step:
 {'state': {2187292089544: {'momentum_buffer': tensor([[6.5132, 6.5132],
        [6.5132, 6.5132]])}}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [2187292089544]}]}
#2187292089544 就是参数的地址,这样保存了可以用于下次训练

学习率

梯度下降:

学习率控制更新的步伐

Momentum动量

结合当前梯度与上次更新信息,用于当前更新(沿着正确的方向,更新速度越来越快)

指数加权平均

每一步将两个梯度方向做一个合并(历史梯度和当前梯度),距离当前时刻越远,对当前值的影响越小,权重越小。

值越大,记忆时间越长,就是距离当前越远的点的影响也能保持下来:

beta对影响时间的长短

一般选择为0.9,就是关注10个点的数据,

梯度下降:

pytorch中的动量算法:



可见,在的作用下,距离当前点越远的梯度信息对当前作用越小

带动量和不带动量的loss.png

带有动量的出现震荡现象是因为梯度大,在取得最小值的情况下收到之前动量信息的影响出现反弹的情况。

optim.SGD 随机梯度下降

批量梯度下降,每一次计算都要将样本中的所有信息进行批量计算;

随机梯度下降,每次迭代随机选取一个样本来对参数进行更新,方向具有不确定性,避免了陷入局部最优

import torch.optim as optim
optimizer = optim.SGD([x], lr=lr, momentum=momentum)
'''
参数:momentum:动量大小一般选择0.9,
    weight_decay:L2正则化系数
    nesterov:是否采用NAG,默认false
对于90%的模型都能使用
'''
for iter in range(iteration)
    y = func(x)
    y.backward()

    optimizer.step() #参数优化
    optimizer.zero_grad()
# 每次迭代完,梯度清零

optim.Adagrad 自适应梯度下降

class torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0)

实现Adagrad优化方法(Adaptive Gradient),Adagrad是一种自适应优化方法,是自适应的为各个参数分配不同的学习率。这个学习率的变化,会受到梯度的大小和迭代次数的影响。梯度越大,学习率越小;梯度越小,学习率越大。缺点是训练后期,学习率过小,因为Adagrad累加之前所有的梯度平方作为分母。

optim.RMSprop 均方根(root meam square)

class torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)

参数更新:w:=w-a\frac{g(w)}{\sqrt{S_{dw}}} \quad b:=b-a\frac{g(b)}{\sqrt{S_{db}}} \quad g表示梯度\quad b,w两个参数\\ 同:\Delta\theta = -\frac{\lambda}{\delta+\sqrt{S_{d\theta}}}*g \quad g是梯度\quad \lambda 学习率\\ S_{db} = \beta*S_{db}+(1-\beta)*g(b)^2 \quad 梯度平方 \quad S初始为0

RMSprop优化方法(Hinton提出),RMS是均方根(root meam square)的意思。RMSprop是对Adagrad的一种改进。RMSprop采用均方根作为分母,可缓解Adagrad学习率下降较快的问题。并且引入均方根,可以减少摆动(原理同自适应,抑制大的,增长小的)。

optim.Adam(AMSGrad)

class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)

使用梯度一阶矩(均值)和二阶矩(方差)
初始化时间步t=0\quad s一阶矩,r二阶矩,g是梯度,\rho(为pytorch中\beta)取值在[0,1]\\ s:=\rho_1*s+(1-\rho_1)*g \\ r:=\rho_2*r+(1-\rho_2)*g^2\\ 修正一阶矩:s = \frac{s}{1-\rho_1^t}\\ 修正二阶矩:r = \frac{r}{1-\rho_2^t}\\ \Delta\theta = -\frac{\lambda*s}{\delta+\sqrt{r}}*g \quad g是梯度\quad \lambda 学习率\\

实现Adam(Adaptive Moment Estimation))优化方法。Adam是一种自适应学习率的优化方法,Adam利用梯度的一阶矩估计和二阶矩估计动态的调整学习率。Adam结合了Momentum和RMSprop,并进行了偏差修正。

你可能感兴趣的:(pytorch 优化器)