了解学习速率以及它如何提高深度学习的表现
2018年02月06日 由 yining 发表
830779
0
学习速率是深度学习中的一个重要的超参数,如何调整学习速率是训练出好模型的关键要素之一。这篇文章将着重说明以下几点:
- 什么是学习速率? 它的意义是什么?
- 如何系统地达成一个良好的学习速率?
- 为什么我们要在训练期间改变学习速率?
- 在使用预先训练的模型时,我们如何处理学习速率?
首先,学习速率是什么呢? 学习速率是一个超参数,它控制了我们在多大程度上调整了我们的网络的权重,并对损失梯度进行了调整。值越低,沿着向下的斜率就越慢。虽然这可能是个好的办法(使用低学习率),以确保我们不会错过任何局部极小值,但这也可能意味着我们要花很长时间才会收敛——尤其是如果我们陷入了停滞不前的区域。下面的公式显示了这种关系。
new_weight = existing_weight — learning_rate * gradient
梯度下降与小(上)和大(底)学习速率。来源:Coursera的机器学习课程
一般来说,学习速率是由用户随意地配置的。在最好的情况下,用户可以利用过去的经验(或其他类型的学习材料)来获得关于设置学习速率的最佳值。
同样的,我们通常很难把它做对。下图演示了在配置学习速率时会遇到的不同场景。
不同学习速率对收敛的影响
此外,学习速率影响了我们的模型是如何收敛一个局部极小值(也就是达到最精确的精度)。因此,从得到的结果中得到正确的结果将意味着我们将花费更少的时间来训练模型。
训练时间越少,花在GPU云计算上的钱就越少。
有更好的方法来确定学习速率吗?
在每次迭代中,你都可以通过非常低的学习速率来训练模型,并将其(线性或指数级)增加,从而估算出良好的学习速率。
每个mini-batch迭代后学习速率提高
如果我们在每次迭代中记录学习情况,并将学习速率(log)与损失(loss)进行划分;我们会看到随着学习速率的增加,会在一个点上,损失停止下降并开始增加。在实践中,我们的学习速率最好是在留在某个地方,也就是图表的最低点(如下图所示)。在这种情况下,最低点的范围在0.001到0.01之间。
上面的办法似乎是有用的。
我如何开始使用它?
目前,在fast.ai包中,它被作为一个函数来支持,这由杰里米·霍华德开发的人工智能包,是一种抽象pytorch包的方法(就像Keras是一种对Tensorflow的抽象)。只需输入以下命令,就可以在训练神经网络之前找到最优的学习速率。
# learn is an instance of Learner class or one of derived classes like ConvLearner
learn.lr_find()
learn.sched.plot_lr()
提高性能
我们已经讨论了学习速率是什么,它是很重要的,并且当我们开始训练我们的模型时,我们如何系统地达到一个最优值。接下来,我们将学习如何使用学习速率来提高我们模型的性能。
通常,当一个人设定好学习速率并训练模型时,他只会等待学习速率随着时间的推移而下降,而模型最终会趋于一致。然而,当梯度到达一个稳定状态时,训练的损失就会变得更加难以改善。极小化损失的难度来自于鞍点,而不是局部极小值。
误差曲面上的一个鞍点。鞍点是一个函数的导数为零的点,但点不是所有轴上的局部极值。
那么我们该怎么办呢? 我们可以考虑一些选择。一般来说,如果训练不再改善我们的损失,我们要改变学习速率每次迭代过程中根据一些循环函数f。每次循环都有一个固定长度的迭代次数。该方法可以使学习速率在合理的边界值之间变化。这很有帮助,因为如果我们被卡在鞍点上,增加学习速率就可以让鞍点达到平稳状态时更快地遍历。这有一种“三角形”的方法,在每几次迭代之后,学习速率就会重新开始。
“三角形”(上)和“三角形2”(下)方法。在上图中,最小和最大学习速率保持不变。在下图中,每次循环后,差异就减少了一半。
另一种很受欢迎的方法叫做“随机梯度下降法”。该方法主要使用余弦函数作为循环函数,并在每次循环的最大程度上重新启动学习速率。当学习速率重新启动时,它并不是从零开始,而是从模型在最后的步骤中收敛的参数开始。
虽然有一些变化,但是下面的图展示了它的一个实现,其中每个循环都被设置为相同的时间周期。
SGDR图,学习速率vs迭代
因此,我们现在有了一种减少训练时间的方法,基本上是周期性地在“山峰”(下图)上跳跃。
标准的学习速率和循环的学习速率
除了节省时间,使用这些方法可以在不调整和减少迭代的情况下提高分类精度。
在迁移学习中的学习速率
在解决人工智能问题时,fast.ai的课程在充分利用预先训练过的模型方面给予了很大的重视。例如,在解决图像分类问题时,学生们被教如何使用预训练的模型,比如VGG或Resnet50,并将其与你想预测的任何图像数据集连接起来。
在fast.ai(程序,不要与fast.ai包混淆)中总结模型是如何快速构建的,下面是我们通常采取的8个步骤:
1.启用数据增强,并设置预计算(precompute)=True
2.使用lrfind()找到最高的学习速率,其中损失仍在明显改善。
3.为1-2个epoch的预计算激活训练最后一层
4.用数据增强的方法(即预计算=False)进行最后一层的训练,使用cyclelen=1的2-3个周期
5.解冻所有的层
6.将较早的层设置为比下一个更高层的3x-10x降低的学习速率
7.再次使用lr_find()
8.用cycle_mult=2训练整个网络,直到过度拟合
在最后一节中,我们将讨论微分学习。
微分学习是什么?
微分学习是一种方法,在训练期间,你将不同的学习速率设置在网络的不同层。这与人们通常如何配置学习速率形成了鲜明的对比,即在训练过程中,在整个网络中使用相同的速率。
为了更清楚地说明这个概念,我们可以参考下面的图,在这个图中,一个预先训练的模型被划分为3个组,每个组将被配置成一个递增的学习速率值。
以微分学习速率抽样的卷积神经网络(CNN)
这种配置方法背后的直观看法是,最初的几层通常包含非常详细地数据细节,比如线条和边缘——我们通常不希望改变太多,并希望保留信息。因此,不需要大量的改变它们的权重。
相反,在之后的层中,比如上面的绿色部分,我们可以看到数据的细节; 并且可能并不需要对它们进行保留。