深度学习优化算法(未完)

概述

深度学习优化算法经历了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 这样的发展历程

优化算法通用框架

首先定义:待优化参数:w ,目标函数: f(w),初始学习率 α。而后,开始进行迭代优化。在每个epoch t:

  1. 计算目标函数关于当前参数的梯度:

  2. 根据历史梯度计算一阶动量和二阶动量:

  3. 计算当前时刻的下降梯度:

  4. 根据下降梯度进行更新:

掌握了这个框架,你可以轻轻松松设计自己的优化算法。

我们拿着这个框架,来照一照各种玄乎其玄的优化算法的真身。步骤3、4对于各个算法都是一致的,主要的差别就体现在1和2上。

BGD

Batch gradient descent

梯度更新规则:

BGD 采用整个训练集的数据来计算 cost function 对参数的梯度:

缺点:

由于这种方法是在一次更新中,就对整个数据集计算梯度,所以计算起来非常慢,遇到很大量的数据集也会非常棘手,而且不能投入新数据实时更新模型。

我们会事先定义一个迭代次数 epoch,首先计算梯度向量 params_grad,然后沿着梯度的方向更新参数 params,learning rate 决定了我们每一步迈多大。

Batch gradient descent 对于凸函数可以收敛到全局极小值,对于非凸函数可以收敛到局部极小值。

SGD

SGD(Stochastic gradient descent)

梯度更新规则:

和 BGD 的一次用所有数据计算梯度相比,SGD 每次更新时对每个样本进行梯度更新,
对于很大的数据集来说,可能会有相似的样本,这样 BGD 在计算梯度时会出现冗余,
而 SGD 一次只进行一次更新,就没有冗余,而且比较快,并且可以新增样本。

缺点:

  • SGD最大的缺点是下降速度慢
  • SGD 因为更新比较频繁,会造成 cost function 有严重的震荡。

  • BGD 可以收敛到局部极小值,当然 SGD 的震荡可能会跳到更好的局部极小值处。

  • 当我们稍微减小 learning rate,SGD 和 BGD 的收敛性是一样的。

SGDM

SGD with Momentum

为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量:

一阶动量是各个时刻梯度方向的指数移动平均值,约等于最近 1/(1-β1) 个时刻的梯度向量和的平均值。

也就是说,t 时刻的下降方向,不仅由当前点的梯度方向决定,而且由此前累积的下降方向决定。β1的经验值为0.9,这就意味着下降方向主要是此前累积的下降方向,并略微偏向当前时刻的下降方向。想象高速公路上汽车转弯,在高速向前的同时略微偏向,急转弯可是要出事的。

NAG

SGD with Nesterov Acceleration
SGD 还有一个问题是困在局部最优的沟壑里面震荡。想象一下你走到一个盆地,四周都是略高的小山,你觉得没有下坡的方向,那就只能待在这里了。可是如果你爬上高地,就会发现外面的世界还很广阔。因此,我们不能停留在当前位置去观察未来的方向,而要向前一步、多看一步、看远一些。

(source: http://cs231n.github.io/neural-networks-3)

这一方法也称为NAG,即 Nesterov Accelerated Gradient,是在SGD、SGD-M 的基础上的进一步改进,改进点在于步骤 1。我们知道在时刻 t 的主要下降方向是由累积动量决定的,自己的梯度方向说了也不算,那与其看当前梯度方向,不如先看看如果跟着累积动量走了一步,那个时候再怎么走。因此,NAG在步骤 1,不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向:

然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤 2 中当前时刻的累积动量。

AdaGrad

上面提到的方法对于所有参数都使用了同一个更新速率。但是同一个更新速率不一定适合所有参数。比如有的参数可能已经到了仅需要微调的阶段,但又有些参数由于对应样本少等原因,还需要较大幅度的调动。

Adagrad就是针对这一问题提出的,自适应地为各个参数分配不同学习率的算法。

其中gt 同样是当前的梯度,连加和开根号都是元素级别的运算。eta 是初始学习率,由于之后会自动调整学习率,所以初始值就不像之前的算法那样重要了。而ϵ是一个比较小的数,用来保证分母非0。

其含义是,对于每个参数,随着其更新的总距离增多,其学习速率也随之变慢。

Adadelta

Adagrad算法存在三个问题

其学习率是单调递减的,训练后期学习率非常小
其需要手工设置一个全局的初始学习率
更新xt时,左右两边的单位不统一
Adadelta针对上述三个问题提出了比较漂亮的解决方案。

首先,针对第一个问题,我们可以只使用adagrad的分母中的累计项离当前时间点比较近的项。

这里ρ是衰减系数,通过这个衰减系数,我们令每一个时刻的gt随之时间按照ρ指数衰减,这样就相当于我们仅使用离当前时刻比较近的gt信息,从而使得还很长时间之后,参数仍然可以得到更新。

RMSprop

RMSprop 是 Geoff Hinton 提出的一种自适应学习率方法。

RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的,

梯度更新规则:

RMSprop 与 Adadelta 的第一种形式相同:

超参数设定值:
Hinton 建议设定 γ 为 0.9, 学习率 η 为 0.001。

Adam

是前述方法的集大成者。我们看到,SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。

SGD的一阶动量:

加上AdaDelta的二阶动量:

优化算法里最常见的两个超参数就都在这里了,前者控制一阶动量,后者控制二阶动量。

实践表明,Adam 比其他适应性学习方法效果要好。

Nadam

Adam是集大成者,但它居然遗漏了Nesterov,这还能忍?必须给它加上——只需要按照NAG的步骤1来计算梯度:

这就是Nesterov + Adam = Nadam了。

说到这里,大概可以理解为什么说 Adam / Nadam 目前最主流、最好用的算法了。无脑用Adam/Nadam,收敛速度嗖嗖滴,效果也是杠杠滴。

感谢:
https://blog.csdn.net/jiachen0212/article/details/80086926
https://blog.csdn.net/w113691/article/details/82631097


原文出处:/show_1EF3qgUE5DI8.html