神经网络在训练过程中的每一个时刻,都有一定的损失或误差,这是通过成本函数(也称为损失函数)计算出来的。此函数表明网络(参数)根据训练或验证数据的“错误”程度。最理想的情况是,损失尽可能的低。不幸的是,成本函数是非凸的——它们不是只有一个最小值,而是有很多很多的局部最小值。
为了最大程度地减少神经网络的损失,使用了一种称为反向传播的算法。反向传播针对神经网络中的参数计算成本函数的导数。换句话说,它找到了更新参数的“方向”,从而使模型的性能更好。这个“方向”称为神经网络的梯度。
在用梯度更新模型之前,梯度乘以一个学习率,这将生成神经网络的实际更新。当学习率过高时,我们可能会跳过最小值,这意味着模型没有达到应有的效果。当学习率太低时,优化过程会非常缓慢。学习率低的另一个风险是,可能会以局部最小值结束。
大多数优化器会自动计算学习率。一个好的优化器可以快速训练机器学习模型,同时也可以防止机器学习模型陷入局部最小值。
常用优化器
SGD
静态学习率并不意味着每次迷你批处理后都会有相等的更新。随着优化器接近(次优)值,其梯度开始减小。
随机梯度下降,简称SGD,是最简单的优化算法之一。在整个训练阶段,它只对所有参数使用一个静态学习率。静态学习率并不意味着在每一个minibatch之后都进行相同的更新。当优化器趋近于最优值时,其梯度开始减小。
AdaGrad
AdaGrad与SGD非常相似。设计的关键区别在于AdaGrad使用了自适应梯度——它对神经网络中的每一个参数都有不同的学习率。由于网络中的所有参数都不是同等重要的,所以以不同的方式更新它们是完全合理的。
AdaGrad根据更新频率更新每个参数的学习率。经常更新的参数会以非常低的学习速度非常仔细地训练。不经常更新的参数以较高的学习率进行训练,以使它们更有效。
RMSProp
AdaGrad存在一个问题,即几次batches之后学习率就会降低,从而导致训练时间长。RMSProp试图通过指数衰减学习速率来解决此问题。、
通过使用过去的学习速率,AdaGrad和RMSProp都使用momentum进行更新。这可以比作把一个球(神经网络状态)滚下山(成本函数图)。球在某个方向上移动的时间越长,速度就越快,这就给了球更高的动量。
球的动量是有用的,因为它允许网络“滚动”到局部的最小值,而不是陷入其中。
Adam
Adam使用AdaGrad和RMSProp这样的过去学习率。但是,Adam还使用了过去的梯度来加快学习。
比较测试
首先导入Python库
MNIST
Python实现代码如下
尽管MNIST是一个小的机器学习数据集,并且被认为是很容易训练的,但是在优化器的性能上有一些明显的差异。SGD是迄今为止最差的优化器,这一点在所有图中都可以看到。RMSProp和Adam在MNIST上的表现非常相似(事实上几乎相同)。
这是可以预料的,因为它们的主要区别在于Adam使用了梯度作为动量,并且MNIST是一个非常小的数据集,因此它的梯度也很小。
CIFAR10
Python实现代码如下
在更大的机器学习数据集(如CIFAR10)中,优化器之间的差异变得更加明显。SGD的改进率非常稳定。在以下图表中,AdaGrad的问题非常明显,即学习率在几个epochs后会增加。Adam和RMSProp的表现再次非常相似。
IMDB Reviews
Python实现如下:
IMDB Reviews机器学习数据集(8k subset)是常见的自然语言处理数据集。它只有8000个单词,它的目标是预测评论的情绪:积极还是消极。由于与本文中提到的以前的数据集相比,这个机器学习数据集非常小,因此结果实际上是相同的。
结论
根据这些结果,在开始新的深度学习项目时,可以优选考虑使用Adam或RMSProp作为优化器。在这篇文章中描述的每个任务上,Adam都获得了最高的训练和验证准确性。