优化器详解:以pytorch实现为例

优化器

优化器目的是为了找到模型最优解,即在反向传播中使神经元得到最优的权重参数。假设有一个参数向量x及其梯度dx,那么其最简单的更新形式是:x+=-learning_rate*dx。其中最为重要的是梯度方向如何调整(优化器的选择(torch.optim.)),调整步幅多大(学习率的调节(lr_scheduler.))。
1.1优化器选取
批量梯度下降法的每一步都把整个训练集载入进来进行计算,时间花费和内存开销都非常大,无法应用于大数据集、大模型的场景。
随机梯度下降法则放弃了对梯度准确性的追求,每步仅仅随机采样一个(或少量)样本来估计当前梯度,计算速度快,内存开销小。但由于每步接受的信息量有限,随机梯度下降法对梯度的估计常常出现偏差,造成目标函数曲线收敛得很不稳定,伴有剧烈波动,有时甚至出现不收敛的情况。随机梯度下降看似要震荡很多次,但是其对梯度计算要求很低,相比于批量梯度下降,其收敛速度要快很多,对于噪声不算很多的情形,一般都能正常收敛。
动量的SGD就是对冲mini-batch带来的抖动,可以加快梯度下降的速度(每一次下降虽然略微变慢,但震荡频率大大降低),特别是处理高曲率、小但一致的梯度,或是带噪声的梯度。其本质是使用指数加权平均之后的梯度代替原梯度进行参数更新,即不再是每一次梯度都是独立的情况,而让每一次的参数更新方向不仅仅取决于当前位置的梯度,还受到上一次参数更新方向的影响。这样做好处有:(1)可以通过局部极小点;(2)加快收敛速度;(3)抑制梯度下降时上下震荡的情况。
带动量的从表达式上为:v=muv-learning_ratedx;x+=v
指数加权平均:当参数(衰减系数)为0.9,第100项梯度动量展开为
在这里插入图片描述
现在其实也有种nestrov动量,其与普通动量不同,从理论上对于凸函数能够更好的收敛。其计算的梯度不是当前的梯度,而是加上之前动量后调整过的梯度,得到的是一个向前看的梯度,具体表达为
x_ahead=x+muv;v=muv-learning_rate*dx_ahead;x+=v
在这里插入图片描述
标准动量算法,先在当前O点计算当前批次的梯度 g0(黑色短线), 然后与O点之前积累的动量V0进行叠加,得到蓝色的线 V1,则O点参数就朝着蓝色方向更新;
但是Nestrov方法,先假设O点沿着V0方向更新了参数,到了另一个点,然后在这个点上计算梯度g0’,(黄色的短线),然后此梯度与V0进行叠加,得到更新方向V1’,即黄色的长线,那么O点就朝着黄色方向更新。

在pytorch实现上为:
torch.optim.SGD(params,lr=,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)- 通常默认false,是否使用NAG(Nesterov accelerated gradient)
前面的方法对学习率都是全局的进行操作,并且所有参数学习率的调整都相同。我能不能思考对每个参数采用不同的学习率调整方式呢?
Adagrad:其通过累计每一次梯度的平方,再让学习率除以它的开方。这样就可以改变不同参数的学习率,比如一个参数梯度计算一直很大,通过这个约束,他改变的就越少,同理,当其梯度很小,通过这约束,变化的就越快。
Cache +=da2;x+=-learning_ratedx/(np.sqrt(cache)+eps)
但这样这个cache会变得越来越大,导致权重越来越难以更新,为此提出rmsprop:
其引入一个衰减率(0.9或0.99),使cache不会因时间的累计变得太大
Cache=decay_rate
cache+(1-decay_rate)*dx
2;x+=-learning_ratedx/(np.sqrt(cache)+eps)
借鉴动量的思想,将动量引入rmsprop即adam:
M = bete1
m+(1-beta1)dx; v=beta2v+(1-beta2)(dx**2);
x+=-learning_rate
m/(np.sqrt(v)+eps)
同理adam+nesterov=Nadam
在pytorch中具体为:
torch.optim.Adam(params,lr=0.001,betas=(0.9,0.999),eps=1e-08,weight_decay=0)
Betas:用于计算梯度和梯度平方平均值系数;weight_decay:权重衰减(L2惩罚)(默认0)
1.2学习率调节
学习率调节主要分两类:epoch进行调节;训练中某些参数进行调节
1.2.1Epoch进行调节:根据epoch间隔调节(LambdaLR,StepLR,MultiStepLR);根据函数曲线进行调节(ExponentialLR,CosineAnnealingLR)
(1)torch.optim.lr_scheduler.StepLR ( optimizer , step_size , gamma=0.1 , last_epoch=-1 )
根据step_size间隔将学习率调整为lr*gamma,last_epoch指最后一个epoch的索引值,用于当训练时中断距续训练,-1指从头训练
(2)torch.optim.lr_scheduler.MultiStepLR (optimizer,milestones,gamma=0.1, last_epoch=-1 )
Milestones自己设定数组用于设置学习率下降
(3)torch.optim.lr_scheduler.CosineAnnealingLR
(optimizer,T_max,eta_min=0,last_epoch=-1)
T_max:lr是周期的1/4;eta_min:最小学习率
1.2.2训练中某些参数进行调节有ReduceLROnPlateau
torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,mode=‘min’,factor=0.1,patience=10,verbose=False,threshold=0.0001,threshold_mode=‘rel’,cooldown=0,min_lr=0,eps=1e-08)
当某指标不发生变化时调整学习率,如监视loss不在下降,精度不在上升等,factor:等同于gamma;patience:能忍受该指标多少个step;verbose:是否需要打印学习率信息;threshold:配合 threshold_mode 使用。threshold_mode(str)- 选择判断指标是否达最优的模式。Cooldown:当调整学习率之后,让学习率调整策略冷静一下,让模型再训练一段时间,再重启监测模式;min_lr(float or list):最小学习率;eps:学习率最小衰减值
3warmup机制
由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。其有助于减缓模型在初始阶段对mini-batch的提前过拟合现象,保持分布的平稳,同时有助于保持模型深层的稳定性。
4SWA训练策略
**SWA简单说就是对多个权重模型进行平均,以此提升模型泛化能力。**具体做法可以是在训练前段(80%)先按设定好的学习率调节方式进行训练,然后在训练后段可以考虑设置一个固定的学习率训练,然后在取后段每次迭代的权重的平均作为最后模型权重的平均。或者同样先正常训练前段,训练完成后使用周期性的学习率(余弦退火)在后段额外多训练几轮,对每次训练的权重进行平均得到最后的权重。
为什么SWA策略有效呢?因为模型的参数属于高维空间,通常SGD训练的模型往往收敛到最优解的边界区域,通过平均可以使他们更接近最优解。如下图:对于每次训练SGD模型都落到了边缘区域,但是平均可以使他们接近最优解。同时这种平均在一定程度上也可以提高模型的泛化能力。
在这里插入图片描述

在pytorch如何具体实现呢?
1:创建平均模型:swa_model = AveragedModel(model)
2:更新模型运行的平均值:swa_model.update_parameters(model)
3:swa学习率调整策略:
torch.optim.swa_utils.SWALR(optimizer,anneal_strategy=”linear/cos”,anneal_epoch=5,swa_lr=0.05)
指在每个参数组内的5个epoch将学习率从初始值退火到0.05
4:训练结束时在给定的数据加载器上计算SWA模型的BN统计信息:
Torch.optim.swa_utils.update_bn(loader,swa_model)
5一个示例的代码流程

5一般的规律
通常实验可以先使用adam让模型自适应快速收敛,其效果一般来说还可以,可以快速看下模型大致的能力,但是一般还是会低于经过精细调整的SGD+momentum+学习率调整策略的结果,但是这种组合对参数非常敏感,需要经过多次调节反复实验才能得到最优参数,一般用于最后比赛或论文最终完成的成果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值