[翻译]梯度下降优化算法总结(2)

原文地址:optimizing-gradient-descent。如果熟悉英文的话,强烈推荐阅读原文,毕竟翻译过程中因为个人理解有限,可能会有谬误,还望读者能不吝指出。另外,由于原文太长,分了两部分翻译,上篇主要是梯度下降优化算法的总结,本篇将会是随机梯度的并行和分布式,以及优化策略的总结。

SGD 的并行和分布式

由于大规模数据解决方案和低档集群的存在,使用分布式 SGD 进行进一步加速是明显的选择。

SGD 本身属性是串行的:一步一步地,我们逐渐靠近最小值。运行它可以提供较好的收敛结果,但在大数据集上会非常慢。相反,异步运行 SGD 更快,但各个 worker 间的非优交互会导致收敛结果变差。而且,我们也可以在一台机器上,而无需大量的计算集群来并行化 SGD。接下来的部分就是已经提出来的优化并行和分布式 SGD 的算法和架构。

Hogwild!

Niu et al. [23] 引入了一个叫做 Hogwild! 的更新策略,可以使 SGD 可以在多 CPU 上并行更新。处理器在无需对参数加锁的情况下就可以访问共享内存。但仅在输入的是稀疏数据时才有效,因为每次更新仅修改所有参数的一小部分。他们展示了在这种情况下,更新策略几乎可以达到一个最优的收敛率,因为处理器不太可能覆盖掉有用的信息。

Downpour SGD

Downpour SGD 是 Dean et al. 4在 Google 的 DistBelief 框架中使用的一个异步 SGD 的变种(TensorFlow 的前身)。它在训练数据的子集上并行运行多个模型的复制。它们会把自己的更新发送到一个参数服务器上,而完整的参数被分发到许多的机器上。每个机器负责一小部分的模型参数的存储和更新。然而,因为各个复制模型直接并没有通信,即分享权重或者更新,它们的参数会持续遇到发散、妨碍收敛的问题。

SGD 的延迟容忍算法

McMahan 和 Streeter 12 在 AdaGrad 中加入了延迟容忍算法,进行了并行化扩展,这样不仅使用了过去的梯度,也使用了更新延迟。而这种技术在实践中效果非常好。

TensorFlow

TensorFlow [13] 是 Google 最近开源的大规模机器学习模型的实现和部署的框架。它是基于 DistBelief 的经验,不仅可以在大量的手机设备上运行,还可以在大规模的分布式系统上运行。对于分布式执行,计算图被每个设备分成一个子集,同时 Send/Receive 节点对之间会进行通信。然而,目前开源版本的 TensorFlow 并不支持分布式功能(详见这里)。13.04.16 更新:TensorFlow 的分布式版本已经发布了。

伸缩平均 SGD

Zhang et al. [14] 提出了伸缩平均 SGD(Elastic Averaging SGD,EASGD),通过使用一个伸缩力来连接异步 SGD 的各个 worker 的参数,即参数服务器存储了一个中心变量。这可以让局部变量比中心变量波动更大,理论上可以允许探索更多的参数空间。实验表明该方法可以提高探索能力,进而提升找到新的局部最优的能力。

SGD 优化的其他策略

最后,我们介绍下可以进一步提升 SGD 性能,除了上面提到的以外的策略。对于一些其他常见的技巧总结,可以参考22

洗牌与课程学习方法

一般而言,我们希望避免按照一定的顺序对模型提供训练样本,因为这样可能会使优化算法产生偏差。 因此,在每次的训练 epoch 时,对训练数据进行洗牌是一个好主意。

另一方面,在一些情况下,我们想要逐步解决较难的问题,按照一个合理的顺序提供训练样本可能确实会提高性能,得到一个更好的收敛结果。建立这种合理顺序的方法叫做课程学习16(Curriculum Learning)。

Zaremba 和 Sutskever 17 使用课程学习方法仅可以训练 LSTMs 来估计一些简单的程序,结果显示混合策略比单纯使用一种策略的效果好,因为对样本排序的难度会上升。

批量归一化

为了加快学习,我们一般会使用零均值和方差对参数进行初始化的归一化处理。随着训练的进行,我们会不同程度的更新参数,这样就失去了原有的归一化属性,这会导致训练速度变慢,并随着网络的变深而放大这些变化。

批量归一化(Batch normalization)18在每个 mini-batch 时重新建立起这些归一化属性,而变化也会随着操作进行反向传播。通过对模型架构进行归一化处理,我们就可以使用更高的学习率,而不用太过关注初始化参数。而且,批量归一化有正则化的能力,可以减少(有时甚至可以去除)Dropout 的需求。

Early stopping

根据 Geoff Hinton 所说:“Early stopping(是)华丽的免费午餐”(NIPS 2015 Tutorial slides,第 63 页)。因此你应该在训练时在验证数据集上监控误差,(保持耐心)如果验证误差并没有改善的情况就停止训练。

梯度噪声

Neelakantan et al. 21 对各个梯度更新根据高斯分布 $N(0, \sigma^2_t)$ 添加了噪声:

$ g_{t, i} = g_{t, i} + N(0, \sigma^2_t)$

并根据下面的规则对方差进行更新:

$ \sigma^2_t = \dfrac{\eta}{(1 + t)^\gamma} $

结果显示这种添加噪声的方法让网络对较差的初始化更加的鲁棒,并有助于训练较深和复杂的网络。他们猜测添加的噪声让模型有更多的机会可以跳出并找到新的局部最小,而这在更深的模型中是很常见的。

总结

在本篇博客中,我们先回归了梯度下降的三个变种方法,其中 mini-batch 是最流行的。接着我们深入探讨了 SGD 优化常用的算法:Momentum、Nesterov accelerated gradient、Adagrad、Adadelta、RMSprop、Adam,也包括了优化异步 SGD 的不同算法。最后,我们研究了提升 SGD 的其他策略,比如洗牌和课程学习方法、批量归一化和 early stopping。

我希望本文可以给你提供不同优化算法的本质和行为的一些基本认识。有没有我没有提高的其他算法?你在使用 SGD 加速训练时使用了什么技巧?麻烦写在评论中,一起探讨。

鸣谢

感谢Denny BritzCesar Salgodo 对草稿提供的建议。

参考文献