优化算法怎么做,鲸鱼和灰狼优化算法详解?

营销圈公众号引导关注

文章导读

训练神经网络的核心是对权重参数进行优化,本文从原始的梯度下降法开始总结了优化算法的发展历程,包括SGD,Momentum,NAG,AdaGrad,RMSProp,Adam,Nadam等,并进行对比总结。

目录

  • Gradient Descent
  • Momentum
  • NAG
  • AdaGrad
  • RMSProp
  • Adam
  • Nadam
  • 对比总结

首先我们回顾一下神经网络训练过程的伪代码:

while True:
data_batch = dataset.sample_data_batch()
loss = network.forward(data_batch())
dx = network.backward()
x += learning_rate * dx

训练的第一步是在数据集中采样,第二步是进行前向传播计算损失值,第三步是通过反向传播计算损失函数在神经网络权重参数上的梯度,第四步是进行权重参数的更新。下面总结的优化算法聚焦于循环的第四步。

Gradient Descent

最基础的优化算法是GD,全称Gradient Descent,即梯度下降法。根据每次参数更新使用的样本数据的不同可以分成批量梯度下降法、随机梯度下降法、小批量梯度下降法,在此我们简要回顾一下:

批量梯度下降法:在每一次参数更新时,需要计算整个样本空间所有数据,因此每次迭代速度非常慢,内存消耗巨大,但是由于下降的方向是总体平均梯度,可能得到一个全局最优解。

考虑批量梯度下降算法中,机器的显存可能加载不了整个样本集,是否可以一个样本一个样本的送入更新参数呢?

随机梯度下降法:每次参数更新时,仅选取一个样本计算梯度。虽然训练速度很快,但是每次更新并不是朝着最优的方向前进,所以在梯度下降的过程中会出现震荡,可能从一个局部最优跳到另一个局部最优。

怎样才能既保证优化的速度,又保证收敛的方向呢?

小批量梯度下降:小批量是批量梯度和随机梯度的一个折中方案,对于含有N个训练样本的数据集,每次参数更新,选择一个大小为M(M<N)的批量数据样本计算其梯度。

在Tensorflow等框架中封装的SGD就是小批量梯度下降算法。在更新权重参数时,SGD首先计算损失函数在权重上的梯度,然后向梯度的相反方向更新网络权重,在这个方向上损失函数的下降最快,不断地重复这一过程直到收敛。其伪代码如下:

while True:
      weights_grad= evaluate_gradient(loss_fun, data, weights)
      weights += step_size * weights_grad

算法特性:SGD相比批量梯度和随机梯度虽然在一定程度上加快了训练速度,提高了收敛的准确率,但是它的缺点也很明显:

  • 容易会陷入局部极小值点和鞍点;
  • 小批量采样带来的噪声使损失来回震荡;
  • 参数的学习率固定;

Momentum

Momentum是SGD结合动量的优化算法,动量的概念就是在梯度方向不变的情况下,参数更新加速,一旦梯度梯度方向有变化,更新速度减慢,其意义是有助于加速收敛和减少震荡。

对比下面SGD和Momentum的伪代码:

# SGD
while True:
dx = compute_gradient(x)
x += learning_rate * dx
# SGD + Momentum
vx = 0
while True:
dx = compute_gradient(x)
vx = rho * vx + dx
x += learning_rate * vx

SGD直接使用当前计算的梯度dx,而Momentum将dx替换为了vx。vx是之前每一步计算出来的梯度和当前梯度的加权和,梯度的权重随时间呈指数衰减,也可以称为梯度的指数加权移动平均。如下图所示,右图积累之前的动量来替代原本的梯度,解决左图SGD的摇摆问题:

算法特性:Momentum沿着历史速度的方向对损失函数进行优化。在优化过程中,即便遇到了没有梯度或者梯度很小的点,由于有速度,可以避免陷入局部极小值点和鞍点,抑制震荡。但是仍然存在一些缺陷:

  • 小批量采样造成的梯度噪声影响收敛;
  • 需要人工设置学习率,且学习率固定;

NAG

NAG是Momentum的升级版,全称Nesterov Accelerated Gradient,在Momentum中对参数更新的策略是计算当前位置(红色的点)的梯度向量和速度向量,参数更新的步长是两者的合成。如下图所示:

优化算法怎么做,鲸鱼和灰狼优化算法详解?

而NAG的策略做了一点改变,它首先计算出当前位置的速度向量,然后计算速度向量所指位置的梯度向量,两者的合成作为实际的参数更新步长。

NAG权重参数更新的公式:

优化算法怎么做,鲸鱼和灰狼优化算法详解?

通常在优化的时候,希望可以计算损失函数在同一个位置处的损失和梯度,这样很方便。NAG公式不符合这个要求,在应用的时候比较麻烦。通过换元法可以解决这个问题。

NAG的伪代码如下:

dx = compute_gradient(x)
old_v = v
v = rho * old_v - learning_rate * dx
x += (1 + rho) * v - rho * old_v

算法特性:NAG在梯度较大的跳跃后能够计算对当前梯度进行校正;但其不足之处和Momentum一样,需要人工设置学习率。如下图所示:

Momentum和Nesterov相比于SGD能收敛到更好的最小值;而Nesterov在根据动量项更新位置的梯度后能够更快的找到最优方向。

以上几种优化算法均提到了一个参数学习率固定的缺点,以同样的学习率更新每一个参数,是否很难找到一个最优学习率,难道只能通过多次训练的经验值得到吗?

AdaGrad

AdaGrad是一种自适应学习率优化算法,其思想是在优化过程中,计算梯度平方项,将每一步梯度的平方累加到这个平方项中,在更新权重参数的时候,除以该累加平方项的平方根。伪代码如下:

grad_squared = 0
while True:
    dx = compute_gradient(x)
    grad_squared += dx * dx
    x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

如果权重参数向量在某个方向上的梯度很小,这个方向上历史累加梯度平方和的平方根也是个小的数,两者相除可以使该方向上的步长变大;同理,如果某个方向上的梯度很大,AdaGrad的做法可以使该方向上的步长变小。

此优化算法适合处理稀疏梯度,为每一维参数设定了不同的学习率:压制常常变化的参数,突出稀缺的更新。能够更有效地利用少量有意义样本。

算法特性:AdaGrad只需要设置初始学习率,随着迭代次数的增加,AdaGrad的学习率会变得越来越小。在损失函数是凸函数的情况下,随着学习率减小,慢慢收敛到极值点。但是在损失函数是非凸函数的情况下,由于步长逐渐减小,可能会陷入鞍点或者导致训练过程提前结束。

RMSProp

RMSProp是AdaGrad的升级版,为了解决AdaGrad中积累全部历史梯度,步长随训练时间逐渐减小的问题,RMSProp在AdaGrad的基础上做了改进,主要的思想是让梯度平方项随着迭代次数的增加,按一定的比率衰减。其伪代码如下:

grad_squared = 0
while True:
    dx = compute_gradient(x)
    grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dx * dx
    x += learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

通过自适应学习率优化算法对比固定学习率优化算法,可以发现SGD容易陷入局部最小值或鞍点出不来;Momentum虽然最终也能到达较好的收敛点,但是走了很多弯路,速度较慢;而RMSProp能够很快的找到最优的方向进行收敛;如下图所示:

优化算法怎么做,鲸鱼和灰狼优化算法详解?

算法特性:只关心过去一段时间窗口的下降梯度,解决了二阶动量持续累计,从而导致训练提前结束的问题。但是仍然依赖初始的全局学习率。

Adam

Adam优化算法等于Momentum和Adaptive的结合,在进行权重参数更新时,既进行了历史梯度的加权和,也除以了历史梯度平方和的平方根。其伪代码如下:

first_moment = 0
second_moment = 0
while True:
    dx = compute_gradient(x)
    first_moment = beta1 * first_moment + (1 - beta1) * dx
    second_moment = beta2 * second_moment + (1 - beta2) * dx * dx
    x -= learning_rate * first_moment / (np.sqrt(second_moment) + 1e-7)

虽然已经实现了Momentum和AdaGrad的想法的结合,但这还不是完全的Adam算法,我们再简单改进一下:衰减率大约可以取0.9,是接近1的数。在第一次迭代中,second_moment很小,接近于0,第二次迭代后,second_moment依然很小,导致除以其平方根后得到的步长会很大。这种情况可以称为冷启动造成的问题。

为了避免优化刚开始时步长很大的问题,在上述伪代码中加入偏差校正项,得到了完整的Adam算法:

first_moment = 0
second_moment = 0
for t in range(num_iterations):
    dx = compute_gradient(x)
    first_moment = beta1 * first_moment + (1 - beta1) * dx
    second_moment = beta2 * second_moment + (1 - beta2) * dx * dx
    first_unbias = first_moment / (1 - beta1 ** t)
    second_unbias = second_moment / (1 - beta2 ** t)
    x -= learning_rate * first_unbias / (np.sqrt(second_unbias) + 1e-7)

算法特性:Adam可以说是优化算法的集大成者,在SGD的基础上把一阶动量Momentum和二阶动量Adaptive加了进去。美中不足之处在于少了Nesterov的元素。

Nadam

Nadam是Adam和Nesterov的结合体,Nadam对学习率有了更强的约束,同时对梯度的更新也更加直接。通常在使用带动量的RMSprop,或者Adam的时候,大多可以使用Nadam取得更好的效果。

对比总结

SGD、Momentum、NAG三种优化算法均易受到鞍点的影响;而AdaGrad、RMSprop、Adam、Nadam四种自适应学习率的优化算法能够很快的找到正确的方向。

所以我们可以看到很多初学者不想调参,就直接上Adam作为优化算法。但是有不少文章抨击了无脑使用Adam的问题:

(1)由于采用一定时间窗口的二阶动量,其非单调的特性可能导致震荡不收敛;

(2)自适应学习率算法可能对前期特征过拟合导致错过最优解;

推荐的方法是Adam+SGD的组合形式,先用Adam进行快速下降,然后在使用SGD进行精细化的调优。

好了,这篇文章的内容营销圈就和大家分享到这里,如果大家对网络推广引流和网络创业项目感兴趣,可以添加微信:Sum8338 备注:营销圈引流学习,我拉你进直播课程学习群,每周135晚上都是有实战的推广引流技术和网络创业项目课程分享,当然是免费学!

版权声明:本站部分文章来源互联网用户自发投稿,主要目的在于分享信息,版权归原作者所有,不承担相关法律责任。如有侵权请联系我们反馈邮箱yingxiaoo@foxmail.com,我们将在7个工作日内进行处理,如若转载,请注明本文地址:https://www.yingxiaoo.com/140890.html