理解学习率以及如何提升深度学习的性能

有没有更好的方法来决定学习率?

作者:Hafidz Zulkifli

编译:ronghuaiyang

导读

把学习率用好,也能提升深度学习模型的性能,一起来看看吧!

这篇文章试图记录我对以下主题的理解:

  • 学习率是什么?它的意义是什么?
  • 如何系统地达到一个良好的学习率?
  • 为什么我们在训练过程中要改变学习率?
  • 在使用预训练的模型时,我们如何处理学习速率?

这篇文章大部分是基于过去fast.ai研究员写的东西。这是它的一个简洁版本,以一种让人快速接触到材料的实质的方式排列。请仔细阅读参考资料以了解更多细节。

首先,什么是学习率?

学习率是一个超参数,它控制着我们根据损失梯度调整网络权重的程度。值越低,我们沿着向下的斜率走得越慢。虽然这可能是一个好主意(使用低学习率),以确保我们不会错过任何局部最小值,但这也可能意味着我们将花费很长时间来收敛—特别是当我们陷入平稳地区。

下面的公式显示了这种关系。

 new_weight = existing_weight — learning_rate * gradient

理解学习率以及如何提升深度学习的性能

学习速率小(上)、大(下)的梯度下降法。

通常情况下,学习速率是由用户随机设置的。最好的情况是,用户可以利用过去的经验(或其他类型的学习材料)来获得关于在设置学习速率时使用什么是最佳价值的直觉。

因此,通常很难把它做好。下图演示了在设置学习率时可能遇到的不同场景。

理解学习率以及如何提升深度学习的性能

不同学习速率对收敛性的影响

此外,学习率影响我们的模型收敛到局部最小值的速度(也就是达到最佳精度的速度)。因此,从一开始就把它做好,意味着我们训练模型的时间会更少。

训练时间越少,花在GPU云计算上的钱就越少。:)

有没有更好的方法来决定学习率?

在“Cyclical Learning Rates for Training Neural Networks.”章节3.3中。Leslie N. Smith提出,你可以用一个非常低的学习率来训练模型,并在每次迭代中以线性或指数的方式增加它,从而估计出一个好的学习率。

理解学习率以及如何提升深度学习的性能

每个mini-batch之后,学习率提升

如果我们记录每次迭代的学习情况,并绘制学习速率(log)与损失的关系图,我们会看到随着学习率的增加,会有一个点损失停止减少并开始增加。在实践中,理想情况下,我们的学习速率应该位于图的最左边(如下图所示)。这里是0.001到0.01。

理解学习率以及如何提升深度学习的性能

上面那些东西看起来很有用,我们怎么用呢?

目前它作为函数在fast.ai包中支持,由Jeremy Howard开发的用于抽象pytorch的一个包(很像Keras是Tensorflow的抽象)。

在训练神经网络之前,只需要输入以下命令就可以开始寻找最优的学习速率。

 # learn is an instance of Learner class or one of derived classes like ConvLearner
 learn.lr_find()
 learn.sched.plot_lr()

变得更好

在这一点上,我们已经讨论了学习率的意义,它的重要性,以及当我们开始训练我们的模型时,我们如何系统地得出一个最优值。

接下来,我们将讨论如何使用学习率来改进模型的性能。

传统的思想

通常,当一个人设定他的学习率并训练模型时,他只会等待学习率随着时间的推移而降低,并等待模型最终收敛。

然而,当梯度达到一个平稳区域,训练损失变得更加难以改善。Dauphin等人认为,损失最小化的困难来自鞍点,而不是糟糕的局部极小值。

理解学习率以及如何提升深度学习的性能

误差曲面上的鞍点,鞍点是函数的导数为零的点,但不是所有轴上的局部极值点

我们如何从这里逃脱?

我们可以考虑几个选择。一般来说,

如果训练不再改善我们的损失,我们将根据循环函数f来改变每次迭代的学习率。根据迭代次数,每个周期都有一个固定的长度。该方法使学习速率在合理的边界值之间循环变化。这是有帮助的,因为如果我们被卡在鞍点上,增加学习率可以更快地遍历鞍点平缓区

Leslie提出了一种“三角形”方法,每隔几次迭代就重新启动一次学习速率。

理解学习率以及如何提升深度学习的性能

理解学习率以及如何提升深度学习的性能

Leslie N. Smith提出的循环学习率的“三角”和“三角2”方法。在左边的图中,min和max lr保持不变。在右边,在每个周期之后,差值减半。

另一种同样流行的方法是由Loshchilov & Hutter提出的带有热重启的随机梯度下降法。该方法基本采用余弦函数作为循环函数,在每个循环中以最大的速度重新开始学习。“热启动”来自这样一个事实:当重新启动学习率时,它不是从头开始,而是从模型在最后一步中收敛到的参数开始。

虽然有一些变化,下面的图展示了它的一个实现,其中每个周期被设置为相同的时间间隔。

理解学习率以及如何提升深度学习的性能

SGDR图,学习率vs迭代。

因此,我们现在有一种减少训练时间的方法,基本上是周期性地在“山脉”周围跳跃(见下图)。

理解学习率以及如何提升深度学习的性能

固定LR与循环LR的比较

除了节省时间,研究还表明,使用这些方法可以在不需要调整和更少迭代的情况下提高分类精度。

迁移学习中的学习率

在fast.ai课程中,在解决人工智能问题时强调利用预训练的模型。例如,在解决图像分类问题时,教授学生如何使用预训练的模型,如VGG或Resnet50,并将其连接到你希望预测的任何图像数据集。

在fast.ai中总结模型构建是如何快速完成的。以下是我们通常会采取的几个步骤:

  • 使用数据增强,并且precompute=True
  • 使用lr_find()来查找最高的学习率,在这个学习率下,损失仍在明显改善
  • 在最后一层上使用预先计算的激活训练1-2个epoch
  • 使用数据增强(即precompute=False)对最后一层进行训练,使用cycle_len=1进行2-3个epoch的训练
  • 解冻所有层
  • 将较早的层的学习率设置为比后面的层的学习率低3~10倍
  • 再使用一次lr_find()
  • 使用cycle_mult=2训练整个网络直到过拟合

从上面的步骤中,我们注意到步骤2、5和7与学习率有关。在本文前面的部分中,我们基本上已经讨论了上面提到的2个步骤—我们在这里讨论了如何在训练模型之前获得最佳的学习率。

在下一节中,我们将介绍如何通过使用SGDR来减少训练时间,并通过不时重新启动学习率来提高准确度,从而避免梯度接近于为零的区域。

在最后一节中,我们将讨论微分学习,以及如何使用它来确定带有预训练模型的训练模型的学习率。

什么是可微分学习?

这是一种方法,你可以在训练过程中为网络的不同层次设置不同的学习速率。这与人们通常配置学习速率的方式相反,人们通常在训练期间在整个网络中使用相同的速率。

理解学习率以及如何提升深度学习的性能

我喜欢Twitter的一个原因是—他自己的直接回答

在写这篇文章的时候,Jeremy和Sebastian Ruder一起发表了一篇论文,深入探讨了这个话题。所以我想微分学习率现在有了一个新名字—可分性微调。:)

为了更清楚地说明这个概念,我们可以参考下面的图,其中将一个预训练的模型分成3个组,其中每个组将配置一个递增的学习率值。

理解学习率以及如何提升深度学习的性能

使用微分学习率的CNN例子

这种配置方法背后的直觉是,前几层通常包含非常细粒度的数据细节,比如线条和边缘—我们通常不希望对它们做太多更改,希望保留它们的信息。因此,不需要太多地改变它们的权重。

相比之下,在后面的层中,比如上面绿色的图层,我们可以得到详细的数据特征,比如眼球、嘴巴或鼻子,我们不一定要保留它们。

这与其他finetune方法相比如何?

Fine-tuned Language Models for Text Classification中有人认为对整个模型进行finetune的成本太高,因为有些模型可能有超过100层。因此,人们通常做的是一次只对模型进行一层finetune。

然而,这引入了顺序需求,阻碍了并行性,并且需要多次遍历数据集,从而导致对小型数据集的过拟合。

同时也证明了Fine-tuned Language Models for Text Classification中引入的方法能够提高各种NLP分类任务的准确率和降低错误率(下图)。

理解学习率以及如何提升深度学习的性能

英文原文:https://towardsdatascience.com/understanding-learning-rates-and-how-it-improves-performance-in-deep-learning-d0d4059c1c10

本文为专栏文章,来自:AI公园,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66213.html 。

(1)
上一篇 2019-09-11 05:29
下一篇 2019-09-12 00:44

相关文章

关注我们
关注我们
分享本页
返回顶部