自 Adam 出现以来,深度学习优化器发生了什么变化?

如果将 Adam 优化出现以来产生的关于优化过程的有趣想法按时间顺序排列的话,结果如下:

  • LR Range test + Cyclical LR(《Cyclical Learning Rates for Training Neural Networks》)

  • SGDR(《SGDR: Stochastic Gradient Descent with Warm Restarts》)

  • SGDW(R) and AdamW(R)(《Fixing Weight Decay Regularization in Adam》)

  • 1-cycle policy and super-convergence(《Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates》)

这个来自 Andrej Karpathy 的笑话或多或少是我深度学习项目的一套流程。除非把具有学习率硬编码的代码直接从 GitHub 里复制到所选优化器中,否则我可能只会把 3e-4 放到 Adam 优化器中,然后让模型训练。如果损失减少,今天就可以收工大吉。

但是,那些美好的日子已经一去不复返了。所以在这篇博客中,我将概述一些人们想出来推翻 Adam 的方法。

LR Range Test:不再盲目找最佳学习率

在这之前,如果 3e-4 在我的数据集上无法作用于模型,我会采取两个办法:

  • 如果看不到损失值移动的明确方向,我会降低学习率

  • 如果在小数点后 5 或 6 位才能看到损失减少,我会提高学习率

  • 如有必要,我会再重复上面的过程。

2015 年,Leslie N. Smith 将上述的反复试验法形式化为一种名为 LR Range Test 的技术。这个方法很简单,你只需将模型和数据迭代几次,把学习率初始值设置得比较小,然后在每次迭代后增加。你需要记录学习率的每次损失并将它画出。

LR Range Test 图示。LR 的初始值仅为 1e-7,然后增加到 10。

LR Range Test 图应该包括三个区域,第一个区域中学习率太小以至于损失几乎没有减少,第二个区域里损失收敛很快,最后一个区域中学习率太大以至于损失开始发散。

除了确保你正在选择最佳学习率之外,该技术还可以作为一种「保险」检查。如果 LR Range Test 没有显示上述 3 个区域,或者图中有断层(损失中有 NaN 值),则表示模型中有缺陷或者数据中有错误。在运行模型之前,最好获取一个理想的 LR range 图。

不好的 LR Range 测试结果。断层处也是损失具有 NaN 值的地方。

Cyclical LR :谁说 LR 需要下降

以往的常识是逐步降低学习率或使用指数函数,从而使模型收敛更稳定。

 Leslie Smith 在同一篇论文中挑战了这一观点,他认为,与其单调地降低学习率,不如让学习率在合理范围内进行周期性变化,这样实际上能以更少的步骤提高模型的准确率

在 lr 和 max_lr 范围内循环学习率

lr 和 max_lr 的范围可以通过上述的 LR Range test 技术来确定。这背后的原理是:最优学习率将在处于这个范围内,所以如果学习率在这歌区间变化,大多数情况下你将得到一个接近最优学习率学习率

作者讨论的另一个优点是能够在损失情况下避开鞍点。鞍点位置的梯度较小,因此小的学习率使模型在训练后期遍历这些鞍点时会很慢。通过在后期提高学习率,可以帮助模型更有效地摆脱鞍点。

  • Keras:https://github.com/bckenstler/CLR

  • Pytorch:https://github.com/anandsaha/pytorch.cyclic.learning.rate/blob/master/cls.py

SGDR:性能良好的旧版热重启 SGD

原则上,SGDR 与 CLR 本质是非常相似的,即在训练过程中学习率是不断变化的。

可重启和余弦退火的 SGD。图片来源:https://www.jeremyjordan.me/nn-learning-rate/

其中,主动退火策略(余弦退火)与重启计划相结合。重启是一个「热」重启,因为模型没有像全新模型那样重启,而是在重新启动学习率后,使用重启前的参数作为模型的初始解决方案。这在实现中非常简单,因为你不需要对模型执行任何操作,只需要即时更新学习率

到目前为止,Adam 等自适应优化方法仍然是训练深度神经网络的最快方法。然而,各种基准测试的许多最优解决方案或在 Kaggle 中获胜的解决方案仍然选用 SGD,因为他们认为,Adam 获得的局部最小值会导致不良的泛化。

SGDR 将两者结合在一起,迅速「热」重启到较大的学习率,然后利用积极的退火策略帮助模型与 Adam 一样快速(甚至更快)学习,同时保留普通 SGD 的泛化能力。

  • Keras:https://gist.github.com/jeremyjordan/5a222e04bb78c242f5763ad40626c452

  • 关于 Pytorch 的 PR: https://github.com/pytorch/pytorch/pull/7821/files

AdamW 和 SGDW:错误的权值衰减

「热」启动策略非常好,并且在训练期间改变学习率似乎是可行的。但为什么上一篇论文没有扩展到 AdamR 呢?

论文《Fixing Weight Decay Regularization in Adam》的作者曾说:

虽然我们初始版本的 Adam 在「热」启动时性能比 Adam 更好,但相比于热启动的 SGD 没有什么竞争力。

这篇论文指出,所有流行的深度学习框架(Tensorflow,Pytorch)都在错误的权值衰减中实现了 Adam。作者在论文中提出了以下意见:

  • L2 正则化和权值衰减不同。

  • L2 正则化在 Adam 中无效。

  • 权值衰减在 Adam 和 SGD 中同样有效。

  • 在 SGD 中,再参数化可以使 L2 正则化和权值衰减等效。

  • 主流的库将权值衰减作为 SGD 和 Adam 的 L2 正则化

ImageNet 上的前 5 个测试错误,图片来自原论文。

→他们提出了 AdamW 和 SGDW,这两种方法可以将权值衰减和 L2 正则化的步骤分离开来。

通过新的 AdamW,作者证明了 AdamW(重启 AdamWR)在速度和性能方面都与 SGDWR 相当。

更多细节请参考: https://www.fast.ai/2018/07/02/adam-weight-decay/

在 Pytorch 和 Keras 中有一些针对此修复的请求,所以你应该很快就可以直接从库中使用这个。

一周期策略和超收敛

 在 2018 年的近期工作中,LR Range test 和 CLR 的作者将自己的想法推向了极致,其中循环学习率策略仅包含 1 个周期,因此称作「一周期」策略。

在一周期策略中,最大学习率被设置为 LR Range test 中可以找到的最高值,最小学习率比最大学习率小几个数量级。

整个周期(向上和向下)的长度被设置为略小于训练周期的总数,这样循环结束后有残余时间降低学习率,从而帮助模型稳定下来。

我们可以将这种策略看作是一种探索-开发的权衡,其中周期的前半部分更有可能从某一局部最优跳到另一局部最优,从而有望在最平坦、最广泛的局部最优区域达到稳定。以较大的学习率开始循环的后半部分有助于模型更快地收敛到最优。

一周期策略本身就是一种正则化技术,因此需要对其它正则化方法进行调优才能与此策略配合使用。

在 Imagenet 上训练 Inception-Resnet-v2 时的超收敛

通过这一策略,作者演示了「超收敛」,它达到相同的验证准确率只需要 1/5 的迭代。

这种现象特别值得注意,因为随着可用的标记训练数据受限,收敛效果会增加。

更多细节请参考:https://sgugger.github.io/the-1cycle-policy.html

结论

所以在 2018 年,你应该做什么来代替 3e-4 Adam 工作流程呢?有很多东西需要考虑,如批量大小、动量等。但是,更好的工作流程将是:

  • 使用 LR Range Test 找到最佳学习率,并完整地检查当前模型和数据。

  • 始终使用学习率调度器,该调度器会改变上一步中找到的学习率,可以是 CLR 或 Restart。

  • 如果需要 Adam,请使用具有适当权值衰减的 AdamW,而不是当前流行框架中使用的默认权值衰减。

  • 如果想实现超收敛,可以进一步尝试一周期策略。


原文链接:https://medium.com/vitalify-asia/whats-up-with-deep-learning-optimizers-since-adam-5c1d862b9db0

理论学习率Adam优化器
11
相关数据
深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

调度技术

调度在计算机中是分配工作所需资源的方法。资源可以指虚拟的计算资源,如线程、进程或数据流;也可以指硬件资源,如处理器、网络连接或扩展卡。 进行调度工作的程序叫做调度器。调度器通常的实现使得所有计算资源都处于忙碌状态,允许多位用户有效地同时共享系统资源,或达到指定的服务质量。 see planning for more details

基准技术

一种简单的模型或启发法,用作比较模型效果时的参考点。基准有助于模型开发者针对特定问题量化最低预期效果。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

学习率技术

在使用不同优化器(例如随机梯度下降,Adam)神经网络相关训练中,学习速率作为一个超参数控制了权重更新的幅度,以及训练的速度和精度。学习速率太大容易导致目标(代价)函数波动较大从而难以找到最优,而弱学习速率设置太小,则会导致收敛过慢耗时太长

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

梯度下降技术

梯度下降是用于查找函数最小值的一阶迭代优化算法。 要使用梯度下降找到函数的局部最小值,可以采用与当前点的函数梯度(或近似梯度)的负值成比例的步骤。 如果采取的步骤与梯度的正值成比例,则接近该函数的局部最大值,被称为梯度上升。

准确率技术

分类模型的正确预测所占的比例。在多类别分类中,准确率的定义为:正确的预测数/样本总数。 在二元分类中,准确率的定义为:(真正例数+真负例数)/样本总数

正则化技术

当模型的复杂度增大时,训练误差会逐渐减小并趋向于0;而测试误差会先减小,达到最小值后又增大。当选择的模型复杂度过大时,过拟合现象就会发生。这样,在学习时就要防止过拟合。进行最优模型的选择,即选择复杂度适当的模型,以达到使测试误差最小的学习目的。

动量技术

优化器的一种,是模拟物理里动量的概念,其在相关方向可以加速SGD,抑制振荡,从而加快收敛

图网技术

ImageNet 是一个计算机视觉系统识别项目, 是目前世界上图像识别最大的数据库。

深度神经网络技术

深度神经网络(DNN)是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。

优化器技术

优化器基类提供了计算梯度loss的方法,并可以将梯度应用于变量。优化器里包含了实现了经典的优化算法,如梯度下降和Adagrad。 优化器是提供了一个可以使用各种优化算法的接口,可以让用户直接调用一些经典的优化算法,如梯度下降法等等。优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。用户基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer(tensorflow下的优化器包)等等这些算法。

推荐文章
暂无评论
暂无评论~