优化器

理论

在这里插入图片描述
在这里插入图片描述

然后,按照规定的mini-batch大小,进行划分数据,如下例:

在这里插入图片描述

这里需要注意最后一个mini-batch数据量一般会小于mini-batch大小。

1. 基本算法

1.1随机梯度下降(SGD)

基本思想是通过梯度下降法,使得网络参数不断收敛到全局(或者局部)最小值,但是由于神经网络层数太多,需要通过反向传播算法,把误差一层一层地从输出传播到输入,逐层地更新网络参数。由于梯度方向是函数值变大的最快的方向,因此负梯度方向则是函数值变小的最快的方向。沿着负梯度方向一步一步迭代,便能快速地收敛到函数最小值。如下图:

在这里插入图片描述

迭代公式如下:

在这里插入图片描述

缺点:

第一个局限性在于在学习的过程中学习率
η是固定的,无法根据神经网络训练的程度调整参数;其次在这里只用到了梯度,但是没有用到梯度的变化情况,因此再求函数最优质的过程中走的并不是最短距离;最后该方法明显在高原、鞍点以及局部最小点处表现不佳。

1.2动量梯度下降法(Gradient descent with Momentum)

基本的想法就是计算梯度的指数加权平均数,并利用该梯度更新权重。运行速度几乎总是快于标准的梯度下降算法。动量算法积累了之前梯度指数级衰减的移动平均,并且继续沿该方
向移动。动量的效果如图所示:

在这里插入图片描述

从形式上看,动量算法引入了变量 v (名称动量(momentum))充当速度角色——它代表参数在参数空间 移动的方向和速率。速度被设为负梯度的指数衰减平均。在梯度下降的过程中加入了惯性,使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就可以加快收敛并减小震荡。

迭代公式如下:
在这里插入图片描述
在这里插入图片描述

存在问题:

  1. 不具备一些先知,例如快要上坡时,就知道需要减速了,适应性会更好;

  2. 不能根据参数的重要性而对不同的参数进行不同程度的更新。

1.3 Nesterov算法

受 Nesterov 加速梯度算法 (Nesterov, 1983, 2004) 启发,Sutskever et al. (2013) 提出了动量算法的一个变种。

Nesterov 动量和标准动量之间的区别体现在梯度计算上。Nesterov
动量中,梯度计算在施加当前速度之后。因此, Nesterov 动量可以解释为往标准动量方法中添加了一个校正因子。迭代公式如下:

在这里插入图片描述

2. 自适应学习率算法

神经网络中学习率肯定是难以设置的超参数之一,因为它对模型的性能有显著的影响。动量算法可以在一定程度解决参数迭代这些问题,但这样做的代价是引入了另一个超参数。从而引出下面的自适应学习率算法。

2.1Adagrad算法

AdaGrad 算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值总和的平方根 (Duchi et al., 2011)。具有损失最大偏导的参数相应地有一个快速下降的学习率,而具有小偏导的参数在学习率上
有相对较小的下降。净效果是在参数空间中更为平缓的倾斜方向会取得更大的进步。

在凸优化背景中,AdaGrad 算法具有一些令人满意的理论性质。然而,经验上已经发现,对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小。AdaGrad在某些深度学习模型上效果不错,但不是全部。

迭代公式如下:

在这里插入图片描述

2.2 RMSprop算法

RMSProp 算法
(Hinton, 2012) 修改 AdaGrad 以在非凸设定下效果更好,改变梯度积累为指数加权的移动平均。

AdaGrad旨在应用于凸问题时快速收敛。当应用于非凸函数训练神经网络时,学习轨迹可能穿过了很多不同的结构,最终到达一个局部是凸碗的区域。AdaGrad 根据平方梯度的整个历史收缩学习率,可能使得学习率在达到这样的凸结构前就变得太小了。

RMSProp 使用指数衰减平均以丢弃遥远过去的历史,使其能够在找到凸碗状结构后快速收敛,它就像一个初始化于该碗状
结构的 AdaGrad 算法实例。相比于 AdaGrad,使用移动平均引入了一个新的超参数ρ,用来控制移动平均的 长度范围。

RMSProp 的标准迭代形式,如下:

在这里插入图片描述

结合 Nesterov 动量的迭代形式,如下:

在这里插入图片描述

2.3 Adam算法

Adam(KingmaandBa,2014)是另一种学习率自适应的优化算法。 “Adam’’ 这个名字派生自短语 “adaptive moments’’。

首先,在
Adam 中, 动量直接并入了梯度一阶矩(指数加权)的估计。其次,Adam 包括偏置修正,修正从原点初始化的一阶矩(动量项)和(非中心的)二
阶矩的估计(。

迭代形式如下:

在这里插入图片描述

实践

1.optimizer()基础概念

1.1 参数组(param_groups)

解释:

optimizer 对参数的管理是基于组的概念,可以为每一组参数配置特定的lr,momentum,weight_decay
等等。 参数组在 optimizer 中表现为一个
list(self.param_groups),其中每个元素是dict,表示一个参数及其相应配置,在 dict 中包含’params’、‘weight_decay’、‘lr’ 、'momentum’等字段。

在这里插入图片描述
在这里插入图片描述

1.2 zero_grad()

解释:梯度清零。

在这里插入图片描述

在这里插入图片描述

1.3 state_dict()

解释:获取模型当前的参数,以一个有序字典形式返回。 这个有序字典中,key 是各层参数名,value 就是参数。

在这里插入图片描述
在这里插入图片描述

1.4 load_state_dict(state_dict)

解释::将
state_dict 中的参数加载到当前网络,常用于 finetune。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.5 add_param_group()

解释:给 optimizer
管理的参数组中增加一组参数,可为该组参数定制 lr, momentum, weight_decay 等,在 finetune 中常用。

例如:

optimizer_1.add_param_group({‘params’:
w3, ‘lr’: 0.001, ‘momentum’: 0.8})

在这里插入图片描述
在这里插入图片描述

1.6 Step()

解释:执行一步权值更新。

2. 优化器

2.1 torch.optim.SGD(params, lr, momentum=0, dampening=0,weight_decay=0, nesterov=False)

功能:可实现SGD优化算法,带动量SGD优化算法,带NAG(Nesterov accelerated gradient)动量SGD优化算法,并且均可拥有weight_decay项。

参数:

  1. params(iterable)- 参数组,优化器要管理的那部分参数。

  2. lr(float)- 初始学习率,可按需随着训练过程不断调整学习率。

  3. momentum(float)- 动量,通常设置为0.9,0.8

  4. dampening(float)- dampening
    for momentum ,暂时不了其功能,在源码中是这样用的:buf.mul_(momentum).add_(1 - dampening, d_p),值得注意的是,若采用nesterov,dampening必须为 0.

  5. weight_decay(float)- 权值衰减系数,也就是L2正则项的系数

  6. nesterov(bool)- bool选项,是否使用NAG(Nesterov
    accelerated gradient)

2.2 Momentum

基本思想:通常情况我们在训练深度神经网络的时候把数据拆解成一小批一小批地进行训练,这就是我们常用的mini-batch SGD训练算法,然而虽然这种算法能够带来很好的训练速度,但是在到达最优点的时候并不能够总是真正到达最优点,而是在最优点附近徘徊。另一个缺点就是这种算法需要我们挑选一个合适的学习率,当我们采用小的学习率的时候,会导致网络在训练的时候收敛太慢;当我们采用大的学习率的时候,会导致在训练过程中优化的幅度跳过函数的范围,也就是可能跳过最优点。我们所希望的仅仅是网络在优化的时候网络的损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。

所以Momentum优化器刚好可以解决我们所面临的问题,它主要是基于梯度的移动指数加权平均。

2.3 RMSProp

基本思想:RMSProp算法的全称叫 Root Mean Square Prop,是Geoffrey E. Hinton在Coursera课程中提出的一种优化算法,在上面的Momentum优化算法中,虽然初步解决了优化中摆动幅度大的问题。

为了进一步优化损失函数在更新中存在摆动幅度过大的问题,并且进一步加快函数的收敛速度,RMSProp算法对权重 W和偏置 b的梯度使用了微分平方加权平均数。

2.4 Adam

基本思想:Adam(Adaptive Moment Estimation)算法是将Momentum算法和RMSProp算法结合起来使用的一种算法。

注:

下面以adam为例

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

参数:

params(iterable)-
参数组,优化器要管理的那部分参数。

  1. 如果优化一个网络,网络的每一层看做一个parameter
    group,一整个网络就是parameter groups(一般给赋值为net.parameters()),补充一点,net.parameters()函数返回的parameter groups实际上是一个变成了generator的字典;

  2. 如果同时优化多个网络,有两种方法:
    2.1 将多个网络的参数合并到一起,当成一个网络的参数来优化(一般赋值为[*net_1.parameters(), *net_2.parameters(), …, *net_n.parameters()]或itertools.chain(net_1.parameters(), net_2.parameters(), …,
    net_n.parameters()));
    2.2 将多个网络的参数合并到一起,当成多个网络优化,这样可以很容易的让多个网络的学习率各不相同(一般赋值为[{‘params’: net_1.parameters()}, {‘params’: net_2.parameters()},
    …, {‘params’: net_n.parameters()})。

两个属性:

1.optimizer.defaults: 字典,存放这个优化器的一些初始参数,有:‘lr’, ‘betas’, ‘eps’, ‘weight_decay’, ‘amsgrad’。事实上这个属性继承自torch.optim.Optimizer父类;

2.optimizer.param_groups:列表,每个元素都是一个字典,每个元素包含的关键字有:‘params’, ‘lr’, ‘betas’, ‘eps’, ‘weight_decay’, ‘amsgrad’,params类是各个网络的参数放在了一起。这个属性也继承自torch.optim.Optimizer父类。

举例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值