PyTorch中的11种优化算法使用教程


1. 什么是优化器(Optimizer)

深度学习模型通过引入损失函数,用来计算目标预测的错误程度。根据损失函数计算得到的误差结果,需要对模型参数(即权重和偏差)进行很小的更改,以期减少预测错误。但问题是如何知道何时应更改参数,如果要更改参数,应更改多少?这就是引入优化器的时候了。简单来说,优化器可以优化损失函数,优化器的工作是以使损失函数最小化的方式更改可训练参数,损失函数指导优化器朝正确的方向移动。

Pytorch中的优化器:管理并更新模型中可学习参数(权重和偏差)的值,使得模型输出更接近真实标签。

  • 导数:函数在指定坐标轴上的变化率;
  • 方向导数:指定方向上的变化率;
  • 梯度:一个向量,方向为方向导数取得最大值的方向。

优化器最主要的功能:

  • 管理:优化器管理哪一部分参数;
  • 更新:优化器通过优化策略更新模型中可学习参数的值,通常都会采用梯度下降法。

2. torch.optim

PyTorch Optimizer 官方文档:LINK

2.1 Optimizer 的属性

PyTorch optimizers 基类。

torch.optim.Optimizer(params, defaults)
class Optimizer(object)
      def_init_(self,params,defaults):
      self.defaults=defaults
      self.state=defaultdict(dict)
      self.param_groups=[ ]
      ...
      param_groups=[{'params':param_groups}]
  • defaults:优化器超参数;
  • state:参数的缓存,如momentum的缓存;
  • param_groups:管理的参数组;
  • _step_count:记录更新次数,学习率调整中使用;

2.2 Optimizer 的方法

zero_grad():清空所管理参数的梯度。

zero_grad()

由于Pytorch中的grad属性不自动清零,每次计算梯度后都会累加到grad属性中,造成错误;因此,在进行梯度求导(反向传播)之后,通过 zero_grad() 方法进行清零。


step():执行一步更新。

step()

当计算出loss,并用loss进行反向传播求出各个参数的梯度之后,使用step()更新权值参数。step() 会采用梯度下降的策略。比如动量法,随机梯度下降,自适应学习率方法等。


add_param_group():添加参数组。

add_param_group()

优化器管理很多参数,其中有些参数可以分组,对于不同组的参数,有不同的超参数设置,例如在某一模型中,希望特征提取部分的权值参数的学习率小一点,学习更新慢一点,这时可以把特征提取的参数设置为一组参数,而对于后面全连接层,希望其学习率大一点,学习快一点。这时,可以把整个模型参数设置为两组,一组为特征提取部分的参数,另一部分是全连接层的参数,对这两组设置不同的学习率或超参数,此时就需要用到参数组概念。


state_dict ():获取优化器当前状态信息 字典

state_dict ()

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

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

以上两个方法用于保存模型某个状态的信息,可以在模型训练过程中,从断点处恢复训练。


3. 学习率

梯度下降(不带学习率参数的更新公式): w i + 1 = w i − g ( w i ) w_{i+1} = w_i - g(w_i) wi+1=wig(wi)
假设有目标函数 y = f ( x ) = 4 x 2 y = f(x) = 4 x^2 y=f(x)=4x2,求导后有 y ′ = f ′ ( x ) = 8 x y' = f'(x) = 8x y=f(x)=8x
在这里插入图片描述

下面计算梯度更新情况:

  • x 0 = 2 , y 0 = 16 , f ′ ( x 0 ) = 16 x_0 = 2,y_0 = 16,f'(x_0)=16 x0=2y0=16f(x0)=16
  • x 1 = x 0 − f ′ ( x 0 ) = 2 − 16 = − 14 x_1 = x_0 - f'(x_0) = 2-16 = -14 x1=x0f(x0)=216=14
  • x 1 = − 14 , y 1 = 784 , f ′ ( x 1 ) = − 112 x_1 = -14,y_1 = 784,f'(x_1) = -112 x1=14y1=784f(x1)=112
  • x 2 = x 1 − f ′ ( x 1 ) = − 14 + 112 = 98 , y 2 = 38416 x_2 = x_1 - f'(x_1) = -14+112 = 98,y_2 = 38416 x2=x1f(x1)=14+112=98y2=38416
  • . . . . . . ...... ......

由以上推导可以看出,在更新到第二步时,梯度已经比较大了,预测值增加了几个数量级,出现了梯度爆炸的情况,这样会导致模型不可用。应对以上这种问题,通常还需要在权重更新时添加学习率参数,以控制更新的幅度。于是梯度更新公式变为:

  • w i + 1 = w i − L R ∗ g ( w i ) w_{i+1} = w_i - LR * g(w_i) wi+1=wiLRg(wi)

学习率直接影响模型能够以多快的速度收敛到局部最小值,即达到最好的精度。一般来说,学习率越大,神经网络学习速度越快。如果学习率太小,网络很可能会陷入局部最优;但是如果太大,超过了极值,损失就会停止下降,在某一位置反复震荡。

针对上文提到的目标函数,探究不同学习率的影响:

学习率 设置为 1:
在这里插入图片描述
学习率设置为 0.4 :
在这里插入图片描述
学习率设置为 0.2:
在这里插入图片描述
学习率设置为0.1:
在这里插入图片描述
由以上分析可以看出,合适的学习率可以加快模型的收敛,该参数是模型优化过程中最重要的超参数之一。下面分析不同学习率的损失曲线:
在这里插入图片描述
上图进一步印证了学习率并非绝对的越大或越小就好,二是针对不同的数据集和模型有其最佳的学习率,针对本例的目标函数,最佳的学习率设置为 0.125 0.125 0.125 左右。


4. Momentum

动量,冲量(Momentum):结合当前梯度与上一次更新信息,用于当前更新。参数更新时在一定程度上保留之前更新的方向,同时又利用当前batch的梯度微调最终的更新方向,简言之就是通过积累之前的动量来加速当前的梯度。
在这里插入图片描述
图自:LINK

当一个小球从山上向下滚,没有阻力时,它的动量会越来越大(速度越来越快),但是如果遇到了阻力,速度就会变小。动量优化法就是借鉴此思想,使得梯度方向在不变的维度上,参数更新变快,梯度有所改变时,更新参数变慢,这样就能够加快收敛并且减少动荡。

在这里插入图片描述
其核心思想是以指数式递减加权的移动平均。各数值的加权而随时间而指数式递减,越近期的数据加权越重,但较旧的数据也给予一定的加权。

上式中, v t v_t vt 是当前时刻的平均值,当前时刻的参数 θ t \theta_t θt ,其所占权重为 1 − β 1-\beta 1β β \beta β 是参数, v t − 1 v_{t-1} vt1 是上一时刻的平均值。假设要求第100天的平均气温 v 100 v_{100} v100 v t v_t vt 表示到第 t t t天的平均温度值, θ t \theta_t θt 表示第 t t t天的温度值,经过推导可以得到:
∑ i N ( 1 − β ) ∗ β i ∗ θ N − i \sum^{N}_{i} (1-\beta) * \beta^i * \theta_{N-i} iN(1β)βiθNi

β \beta β 设置为 0.9,绘图得:
在这里插入图片描述
可以看出时间越远,对第100天温度的影响越小。下面探究一下不同 β \beta β 值的影响:

在这里插入图片描述
β \beta β 可以看作记忆周期, β \beta β 越大,记忆周期越长,反之,越短。 β \beta β 通常设置为0.9,其物理意义为只关注十天左右的数据对当前的影响。


Momentum 更新公式:

  • v i = m ∗ v i − 1 + g ( w i ) v_i = m * v_{i-1} + g(w_i) vi=mvi1+g(wi)
  • w i + 1 = w i − l r ∗ v i w_{i+1} = w_i - lr * v_i wi+1=wilrvi

其中 w i + 1 w_{i+1} wi+1 表示第 i + 1 i+1 i+1 次更新的参数, v i v_i vi 表示更新量, m m m 表示衰减系数, l r lr lr 表示学习率。


衰减系数对模型的影响:
在这里插入图片描述
在这里插入图片描述
由上图可知,当动量比较大时,损失容易出现震荡;恰当的动量参数设置,可以使模型更快收敛。


5. PyTorch 优化器

优化器综述Paper:

A Survey of Optimization Methods from a Machine Learning Perspective


5.1 torch.optim.SGD

torch.optim.SGD 可实现SGD优化算法,带动量SGD优化算法,带 NAG(Nesterov accelerated gradient) 动量SGD优化算法,并且有 weight_decay 项。

torch.optim.SGD(params, 
                lr=<required parameter>, 
                momentum=0, 
                dampening=0, 
                weight_decay=0, 
                nesterov=False)

参数说明:

  • params (iterable):参数组,优化器要管理的那部分参数。
  • lr (float):初始学习率,可按需随着训练过程不断调整学习率。
  • momentum (float):动量,通常设置为0.9,0.8。
  • dampening (float):若采用 nesterov,dampening 必须为 0。
  • weight_decay (float):权值衰减系数,即L2正则项的系数。
  • nesterov (bool):bool,是否使用 NAG(Nesterov accelerated gradient)。

5.2 torch.optim.Adagrad

torch.optim.Adagrad(params, 
                    lr=0.01, 
                    lr_decay=0, 
                    weight_decay=0, 
                    initial_accumulator_value=0, 
                    eps=1e-10)

【Paper】:LINK


5.3 torch.optim.RMSprop

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

【Paper】:LINK


5.4 torch.optim.Adadelta

torch.optim.Adadelta(params, 
                     lr=1.0, 
                     rho=0.9, 
                     eps=1e-06, 
                     weight_decay=0)

【Paper】:LINK


5.5 torch.optim.Adam(AMSGrad)

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

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

【Paper】:LINK


5.6 torch.optim.Adamax

torch.optim.Adamax(params, 
                   lr=0.002, 
                   betas=(0.9, 0.999), 
                   eps=1e-08, 
                   weight_decay=0)

【Paper】:LINK


5.7 torch.optim.SparseAdam

torch.optim.SparseAdam(params, 
                       lr=0.001, 
                       betas=(0.9, 0.999), 
                       eps=1e-08)

5.8 torch.optim.AdamW

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

【Paper】:LINK


5.9 torch.optim.ASGD

torch.optim.ASGD(params, 
                 lr=0.01, 
                 lambd=0.0001, 
                 alpha=0.75, 
                 t0=1000000.0, 
                 weight_decay=0)

【Paper】:LINK


5.10 torch.optim.LBFGS

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)

5.11 torch.optim.Rprop

torch.optim.Rprop(params, 
                  lr=0.01, 
                  etas=(0.5, 1.2), 
                  step_sizes=(1e-06, 50))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EAI2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值