各类的梯度优化

梯度下降是最流行的优化算法之一并且目前为止是优化神经网络最常见的算法。与此同时,每一个先进的深度学习库都包含各种算法实现的梯度下降(比如lasagne, caffe 和 keras的文档)。然而,这些算法经常作为黑盒优化程序使用,所以难以感受到各种算法的长处和不足。

本次分享旨在为您提供对不同梯度算法的直观感受,以期会帮助您更好地使用不同的梯度下降算法。首先,会罗列各种梯度下降算法的变种并简单地总结算法训练阶段的挑战。然后,会通过展示解决问题的动机和依据这些动机来推导更新法则,以介绍最常见的优化算法。本次也顺带罗列并行分布式环境下的算法和体系结构。最后,会讨论其他有利于梯度下降优化算法的策略。


梯度下降是一种以通过在目标函数梯度

的反向上更新模型参数,来最小化模型参数的目标函数

的方法。学习速率

决定了我们前往(局部)极小值的步长。换言之,我们沿着目标函数所构造曲面的斜面按向下的方向走动,直到我们到达山谷。如果你对梯度下降不熟悉,您可以看之前平台发表过的一篇分享


梯度下降算法变种

存在三种梯度下降的变种,他们不同之处在于我们在计算目标函数梯度时所用数据量的多少。依据数据的规模,我们在更新参数的准确性和执行一次更新所用时间之间进行一种折中。

批量梯度下降

普通的梯度下降,也称批量梯度下降,利用所有的训练数据计算目标函数的梯度。

由于我们每进行一次参数更新需要计算整体训练数据的梯度,批量梯度下降会变得很慢并且一遇到内存吃不下数据就挂了。同时批量梯度下降也无法支持模型的在线更新,例如,新的样本不停的到来。

代码中,批量梯度下降大概长这样:

  1. for i in range(nb_epochs):
  2. params_grad = evaluate_gradient(loss_function, data, params)
  3. params = params - learning_rate * params_grad

对于一个预先定义迭代轮数,我们首先以整体数据计算损失函数的梯度向量weights_grad关于参数向量params。值得注意的是先进的深度学习库提供对一些参数进行自动求导可以有效地计算梯度。如果你是自己来推梯度,梯度检查是一个不错的注意。本平台也推送过梯度求解过程

我们随后以梯度的反方向更新我们的参数,此时学习速率决定着我们每次执行多大的更新。批量梯度下降可以保证在convex error surfaces 条件下取得全局最小值,在non-convex surfaces条件下取得局部极小值。

随机梯度下降

随机梯度下降(SGD)以一个训练样例

和标签

进行一次参数更新。

由于在每次参数更新前对相似的样例进行梯度重复计算, 批量梯度下降会在大数据集上进行冗余计算。SGD通过每次计算一个样例的方式避开这种冗余。因此,SGD速度会更快并支持在线学习。

SGD频繁的执行更新所伴随的高方差(a high variance)会导致目标函数如图1所示的剧烈波动。

批量梯度下降收敛到盆面的极小值,SGD的波动一方面能够使(损失函数)跳到一个全新并且可鞥呢更优的局部极小值,另一方面这种波动由于一直overshooting终究会很难收敛到确切的极小值。然而,(实验)表明当我们慢慢地减小学习速率时SGD表现出和批量梯度下降同样的收敛行为,几乎确定地在non-convex and convex optimization中各自收敛到一个局部或者全局极小值在。

Mini-batch gradient descent

Mini-batch gradient descent 吸收了上述两个算法的长处,利用小批量训练样例执行一次更新。

以这种方式,它可以, a): 减小参数更新的方差,导致更平稳的收敛;b): 利用先进深度学习库中常见的高度优化矩阵操作来高效地计算小批量的梯度。

普通小批量的规模在50-256之间,但在不同的应用中会变化。Mini-batch gradient desent 是训练NN的经典选择,采用mini-bathes常常也会称为SGD。注意在后文中SGD改进中,为简单起见,我们省略参数

挑战

然而,普通的mini-batch gradient descent不能保证较好的收敛性,这一点引出了下述挑战:

  1. 选择一个合适的学习速率是很难的。学习速率太小会导致收敛慢,太大会阻碍收敛并导致损失函数在极小值周围波动甚至背离。
  2. 尝试通过设置调度在训练时候调整训练速率,比如,模拟退火按照预先定义好的调度算法或者当相邻的迭代中目标变化小于一个阈值时候减小学习速率。但是这些调度和阈值需要预先设置,无法对数据集特征进行自适应。
  3. 除此之外,对所有的参数更新都按照同一个学习速率也是一个问题。如果我们的数据很稀疏并且我们的特征出现的次数不同,我们可能不会希望所有的参数以某种相同的幅度进行更新,而是针对很少出现的特征进行一次大幅度更新。
  4. 在神经网络中常见的极小化highly non-convex error functions的一个关键挑战是避免步入大量的suboptimal local minima。Dauphin等人认为实践中的困难来自saddle points而非local minima。所谓saddle points是指那些维度梯度不一致的点。这些saddle points经常被一个相等误差的平原包围,导致SGD很难摆脱,因为梯度在所有方向都近似于0。

梯度下降优化算法

下面我们会概述一些深度学习社区广泛采用的以解决上述挑战的算法。我们不会讨论那些实践中对高维数据集合计算上不可行的算法,比如二阶方法(比如牛顿法)。

Momentum

SGD不那么容易越过ravines,所谓ravines也就是那些surface curves在某个维度比其他维度梯度大得多的地方,这些地方经常在局部极小值周围出现。在这种情况下,SGD会像图2一般沿着slopes of the ravine振荡中前进,在底部磨磨蹭蹭地朝局部最优走。

不带Momentum的SGD

带Momentum的SGD

Momentum是一种帮助SGD在相关方向进行加速并抑制振荡的方法,如图3所示。它通过向当前更新向量中加入上一时刻的更新向量的部分实现上述功能。

注意,有些实现中会对等式中的符号进行变动。momentum term

一般设置为0.9或类似值。

我们向山下丢一个小球就会涉及使用到momentum。小球在向山下滚动时候会积累动量滚动地越来越快(如果存在空气阻力,会一直加速到终端速度terminal velocity)。相同的事情会发生在参数更新上:momentum term会在更新方向相同的维度加速,会在更新方向不同的维度上减速。最终,我们更快地收敛并减少振荡。

Nesterov accelerated gradient

然而,我们并不满意于滚动的小球仅仅只是盲目地沿着斜面slope滚动。我们希望有一个更加聪明的小球,一个知道自己能否认识到自己选择道路的小球,这种小球会在斜面slope再次上倾的时候放慢自己的速度。

Nesterov accelerated gradient (NAG) 是一种能够给我们momentum term带来这种先见之明的方法。我们清楚我们会使用momentum term

来更新参数

。计算

会让我们看到更新后参数的近似值(完整的更新还需要考虑梯度),让我们大致知道参数朝那地方更新。我们现在可以通过计算下一个位置参数的梯度(而不是当前位置的参数) 进行提前准备:

我们再次将momentum term

设置在0.9的附近。不同于Momentum方法先计算当面的梯度(图4中蓝色小向量)后在更新过的累积梯度方向上进行一个大跨越(蓝色大向量),NAG先在上一个累积梯度方向进行跳跃(棕色向量),测量下梯度然后进行一个修正(绿色向量)。这种预期式的更新防止我们走的太快并增加反应能力,显著提高了RNN在一些任务上的性能。

图4. Nesterov更新

现在我们可以让我们的更新适应于损失函数所构造的斜面slope的同时加快SGD的速度。我们也希望我们的更新适应于单独的参数,按照参数自身的重要性来进行大幅度或者小幅度的更新。

算法的可视化

下面两幅动画让我们直观感受一些优化算法的优化过程。

在图中,我们看到他们随着时间推移在损失表面的轮廓(contours of a loss surface)的移动。注意到Adagrad、Adadelta和RMSprop几乎立刻转向正确的方向并快速收敛,但是Momentum和NAG被引导偏离了轨道。这让我们感觉就像看滚下山的小球。然而,由于NAG拥有通过远眺所提高的警惕,它能够修正他的轨迹并转向极小值。


http://img.blog.csdn.net/20160329013917422?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center


图展现了各种算法在saddle point上的表现。所谓saddle point也就是某个维度是positive slope,其他维度为negative lope。前文中我们已经提及了它给SGD所带来的困难。注意到SGD、Momentum和NAG很难打破对称,虽然后两者最后还是逃离了saddle point。然而Adagrad, RMSprop, and Adadelta很迅速地沿着negative slope下滑。


http://img.blog.csdn.net/20160329102417315?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center


采用哪种

现在,问题来了。你现在会采用哪种优化算法呢?如果你的输入数据是稀疏的,你更可能通过采用某种自适应学习速率方法来获得最好的结果。这么做另外一个好处是你不必去调学习速率,仅用默认值就可以取得最好的结果。

总而言之,RMSprop是Adagrad的一种针对处理Adagrad的学习速率减小的扩展。它和Adadelta是一样的,唯一不同就是Adadelta使用在更新规则的分子中使用参数更新的RMS。Adam是将bias-correction and momentum加入到RMSprop中。RMSprop、Adadelta和Adam是很相似的算法并且在相似的环境中性能都不错。Kingma等人发现在优化后期由于梯度越来越稀疏,bias-correction帮助Adam微弱地击败RMSprop。综合看来,Adam可能是最佳选择。

有趣的是,最近很多论文都采用不带momentum的普通SGD和一种简单的模拟退火(annealing schedule)学习速率。SGD常常会达到极小值,但是花掉的时间比其他的算法多得多。SGD在更加依赖于鲁棒的初始化和模拟退火(annealing schedule)并可能被saddle points而不是局部极小值困住。所以,如果你在意快速收敛或者在训练一个很深很复杂的神经网络,你应该采用一种自适应学习速率方法。

并行式与分布式SGD

鉴于无处不在的大规模数据解决方案和低价可得的集群,将SGD进行分布以进一步加速是一个理所当然的选择。

SGD自身是sequential的:我们逐步地朝着极值前进。SGD跑起来收敛性好但是在速度非常慢,尤其是在大数据集上。相反,异步方式的SGD速度很快,但是workers之间次优的通信会导致收敛较差。另外,我们也可以在一台机器上将SGD并行,而不用大的计算集群。下面是一些关于优化并行式和分布式SGD的算法和体系结构。

原文发布于微信公众号 - 计算机视觉战队(ComputerVisionGzq)

原文发表时间:2017-04-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美图数据技术团队

梯度下降优化算法概述

感谢阅读「美图数据技术团队」的第 11 篇原创文章,关注我们持续获取美图最新数据技术动态。

21810
来自专栏人工智能LeadAI

深度学习优化器总结

每次更新我们需要计算整个数据集的梯度,因此使用批量梯度下降进行优化时,计算速度很慢,而且对于不适合内存计算的数据将会非常棘手。批量梯度下降算法不允许我们实时更新...

17730
来自专栏李智的专栏

斯坦福CS231n - CNN for Visual Recognition(8)-lecture6学习率更新、超参数调优

  训练深度网络时,让学习率随着时间退火通常很有帮助。如果学习率很高,系统的动能就过大,参数向量就会无规律地跳动,不能够稳定到损失函数更深更窄的部分去。

10620
来自专栏梦里茶室

TensorFlow 深度学习笔记 Stochastic Optimization

Stochastic Optimization 转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/G...

225100
来自专栏marsggbo

DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、正则化以及优化--Week2优化算法

1. Mini-batch梯度下降法 介绍 假设我们的数据量非常多,达到了500万以上,那么此时如果按照传统的梯度下降算法,那么训练模型所花费的时间将非常巨大,...

22560
来自专栏机器之心

深度 | 从修正Adam到理解泛化:概览2017年深度学习优化算法的最新研究进展

选自Ruder Blog 作者:Sebastian Ruder 机器之心编译 参与:刘晓坤、路雪、蒋思源 Sebastian Ruder 的这篇博客总结了 20...

436120
来自专栏大数据文摘

斯坦福CS231N深度学习与计算机视觉第八弹:神经网络训练与注意点

14330
来自专栏IT派

干货|如何做准确率达98%的交通标志识别系统?

摘要: 我们可以创建一个能够对交通标志进行分类的模型,并且让模型自己学习识别这些交通标志中最关键的特征。在这篇文章中,我将演示如何创建一个深度学习架构,这个架构...

40760
来自专栏人工智能LeadAI

最终章 | TensorFlow战Kaggle“手写识别达成99%准确率

这是一个TensorFlow的系列文章,本文是第三篇,在这个系列中,你讲了解到机器学习的一些基本概念、TensorFlow的使用,并能实际完成手写数字识别、图像...

42690
来自专栏量子位

2017年深度学习优化算法最新进展:如何改进SGD和Adam方法?

原作 Sebastian Ruder 王小新 编译自 ruder.io 量子位 出品 | 公众号 QbitAI 深度学习的基本目标,就是寻找一个泛化能力强的最...

439120

扫码关注云+社区

领取腾讯云代金券