有关梯度优化方法学习总结

背景

在机器学习领域,待解决的问题往往抽象建模成代价函数(cost function), 求解代价函数的最优解便是我们解决这个问题的目标。代价函数的求解便是优化过程,我们需要找到该函数的极小值,最好是最小值,但是最小值通常难以求解。极小值能够使我们的代价函数取值相对小,因而我们可以减少训练集中的损失(loss)。此时,模型便是能够反映整个数据集合的构成的。当然,这里先不考虑过拟合(overfitting)的情况。

然而如何求解代价函数最值,这是一个很棘手的问题。对于只有一个自变量的函数,求解极值可以简单求解二阶导数,但是由于在机器学习范畴简单问题的代价函数通常不只只有一个自变量,因此二阶导数的求解会传换成一个时间复杂度为 n2 的求解 hessian 矩阵问题,因此求解二阶导数往往不是很实用。但是拟牛顿法在今天也在这个领域发挥着它的作用,另外,遗传算法(GA)也展现了强大的优化能力。这些强大的算法都基于梯度,这也是本文着重讲述的。

基于梯度的简单优化方法是初学者最开始接触的优化算法。本文基于 CIFAR10 数据集简单对比 随机梯度下降(stochastic gradient descent),随机梯度下降 + momentum,RMSProp 以及 Adam 算法。

算法总结

代价函数的取值范围在高纬坐标系中可以很明显的看到,例如图一,展示了包含两个自变量 x, y 的代价函数的在每一点的对应取值。随着代价函数的不同,该取值曲面也不同。既然二阶导数已经在效率上不可用,那么能否简单画出每个代价函数的取值然后肉眼观察呢?显然这是一个很可爱的想法。因此,我们最后决定根据梯度的方向进行优化。

总的来说, 梯度是一个矢量,是函数一个点上导数最大值的方向,也就是函数值在该方向上下降最快,因此只要随着梯度的方向,便能最快的到达极值点。梯度下降(gradient descent)的方法就是这么得来的。想象我们在山顶,只要我们每一步都沿着最陡的方向迈出下一步,那么我们一定可以最快到达山脚。因此,找到了梯度,我们也需要小心注意步长值,若步长值太大,我们可能一步迈出过大,错过了极值点,若步长值太小,我们到达极值点的次数会增加。

有关梯度优化方法学习总结
图1 某一代价函数3D图 [1]

随机梯度下降

随机梯度下降也称为小批量梯度下降(mini-batch gradient decent)。一般而言,梯度下降需要在遍历所有的数据后才进行梯度计算然后更新参数。假设现有数据集有10,000条数据,那么在这10,000条数据陡进行训练之后才会确定梯度,这样的计算会耗时很长。随机梯度下降解决的这个需要遍历所有数据才更新一次参数的问题。随机梯度下降根据每一个小批量数据进行更新参数。也就是说,10,000个数据,假设分成10个批量,每个批量是1,000个数据,那么在遍历完每个批量后,计算这个小批量的梯度然后进行更新参数,这样在遍历完10,000个多有数据后,梯度下降实际上已经进行了十次,相比于普通梯度下降而言,速度快了10倍。实验结果表明,在数据打乱情况下,随机梯度下降的每一个批量是可以很好近似整个数据集的。随机梯度下降的参数更新公示如下:

W=Wlr×dW

lr 表示的是学习率(learning rate),也就是下山例子中的步长值,所以学习率的设置影响着优化过程

随机梯度下降 + Momentum

Momentum 通过保持前一步的行动势头从而加速整个 cost function 优化查找的收敛过程。例如当前一步与前一步方向保持一致,那么整个跨出的范围就会大一些,反之则会减小以防跨出的步子太大。可以想象,当当前梯度方向与前一步方向不一致时,通过矢量加法,下降的步伐会平滑很多。

V=mu×Vlr×dW
W=W+V

在上面两条公式中,V初始化为 0 ,记录了前一个步伐的方向和大小。

RMSProp

要开始讨论 RMSProp 算法,得从 Adagrad 算法开始。 从梯度下降到随机梯度下降我们发现,所有的参数都是使用同一个学习率,这并不利于一个模型的学习。想象一个大型神经网络(Neural Network),其中蕴含的参数可能成千上百,要更新每一个参数都得找到符合其自身的学习率。Adagrad 正是基于这个问题而提出的。该算法强调给不同的参数以不同的学习率。因此其核心思想便是:加快减小偏导数大的参数的学习率,而减慢减小偏导数小的参数的学习率。这样的结果便是偏导数大的参数可以通过快速减小步伐而不至于错过极值点,而导数偏小的参数可以保持相对平稳的步伐继续寻找极值点。Adagrad 公式如下:

cache=cache+(dW)2
W=(Wlr×dW)cache+eps

cache 是记录上一个偏导数的缓存, eps 通常设置成1×108 以防止分母为 0。从这两个式子可以看到,cache 是以平方的速度增长并且累积了之前所有的偏导数导数,这很容易造成在偏导数较大的参数在达到满意值之前,学习率就被降低到很小,从而导致该参数的满意值很难被找到。

为了解决这个解决这个问题, RMSProp 算法被提出,增加了一个衰退因子约束学习率的减少。在 RMSProp 算法中, W 的更新和上面保持不变,但是 cache 的更新发生了变化。

cache=dr×cache+(1dr)×(dW)2

dr 代表的是衰退因子(decay rate)通常取值 0.9 - 0.999, 这保证了 cache 的不会增长太快。

Adam

Adam 算法是目前比较流行的一个优化算法,它名字的来源不是源自于人名,也不是缩写,而是 “adaptive moment estimation“ :自适应矩估计,于2015 年在ICLR论文 Adam: A Method for Stochastic Optimisation被提出 [2]。Adam 算法根据导数的一阶矩阵估计和二阶矩估计动态调整学习率。一阶矩估计即是导数的平均值,二阶矩估计即是导数平方的平均值。Adam算法的步骤如下:

m=beta1×m+(1beta1)×dW
v=beta2×v+(1beta2)×(dW)2
mt=m1beta1t
vt=v1beta2t
W=Wlr×mtvt+eps

beta1 通常取值 0.9 , beta2 通常取值 0.999, eps 仍旧取一个微小值防止分母为 0, 其中 mt 和 vt 式子中的 t 代表的是迭代次数,也就是调用了 adam 算法的次数,等价于计算梯度的次数。

实验

该实验建立在 CIFAR10 数据集,该数据集包含了十个不同类别的图片,规格是 32x32x3。CIFAR10 含有50,000张训练集数据,10,000张测试集。本实验的神经网络网络模型是5层隐藏层(hidden layer)网络,每层隐藏层都是100个神经元,输出层是10个神经元,对应着CIFAR10 数据集的输出。

首先,小训练数据采用该数据集大训练集的前4,000张图像,验证集取自该大训练集的最后1,000张图像,验证集和训练机不重叠。参数:学习统一采用 1×103 批量数据大小(batch size)为 100。 参数的初始化统一采用高斯分布。
有关梯度优化方法学习总结
图2 Training loss 1
有关梯度优化方法学习总结
图3 Accuracy 1

从图二可以看到,Adam 把 loss 控制到最小,而随机梯度下降在四种优化算法中表现的最差。在图三看到,Adam 算法在训练集中的准确率最高,然而在验证集中 RMSProp 最高,其中随机梯度下降算法始终是收敛最慢的。但在图二可以看到的是 RMSProp 算法在初期的 loss 非常之高,这也许是因为学习率过高造成的。由于式子中eps的影响,若学习率过高会导致参数的突然增长,让 loss 产生跳变,因此这是要注意的。

于是将 RMSProp 的学习率改成1×104, loss 便不再是刚开始的跳跃式增长了。从图4也可以看到, Adam算法一直把 loss 控制的很好。
有关梯度优化方法学习总结
图4 Training loss 2
有关梯度优化方法学习总结

最后,在训练中推荐使用Adam算法来进行优化。

参考文献

[1] Khademi, Seyran & Svantesson, Thomas & Viberg, Mats & Eriksson, Thomas. (2011). Peak-to-Average-Power-Ratio (PAPR) reduction in WiMAX and OFDM/A systems. EURASIP Journal on Advances in Signal Processing. 2011. 10.1186/1687-6180-2011-38.
[2] 听说你了解深度学习最常用的学习算法:Adam优化算法? | 数盟. [online] Available at: http://dataunion.org/30450.html [Accessed 14 Mar. 2018].