【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

了解学习率及其如何提高深度学习的性能

  • 2018-03-18
  • 本文字数:4152 字

    阅读完需:约 14 分钟

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

  • 什么是学习率?它的意义是什么?
  • 如何系统地达到良好的学习率?
  • 为什么要在训练期间改变学习率?
  • 在使用预训练的模型时,如何处理学习率?

这篇文章的大部分内容,是基于过去 fast.ai 的研究员所写的 [1]、[2]、[5] 和 [4] 的内容的简洁版,以一种快速的方式,获得其精髓。要了解更多细节,请仔细参阅文末所列的参考资料。

AI 前线: fast.ai 是一个致力于为所有人提供学习深度学习机会的平台。他们认为深度学习将是一个转型的技术,正在研究综合利用人类与计算机各自优势的混合“人机”解决方案,建立一个随时可用的应用程序和模型库,开发完整的教育框架,并为开发人员和用户编写能够快速上手和易于使用的软件。

首先,什么是学习率?

学习率(Learning Rate,LR。常用η表示。)是一个超参数,考虑到损失梯度,它控制着我们在多大程度上调整网络的权重。值越低,沿着向下的斜率就越慢。虽然这可能是一个好主意(使用低学习率),以确保我们不会错过任何局部最小值;但也有可能意味着我们将耗费很久的时间来收敛——特别是当我们陷入平坦区(plateau region)的时候。

AI 前线:如果使用很高的学习率,训练可能根本不会收敛,甚至会发散。权重的该变量可能会非常大,使得优化越过最小值,导致损失函数变得更糟。

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

复制代码
new_weight = existing_weight — learning_rate * gradient

复制代码
学习率很小(上图)与学习率很大(下图)的梯度下降。(来源:Coursera 机器学习课程,Andrew Ng)

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

因此,很难做到这一点。下图演示了配置学习率时可能会遇到的不同场景。

复制代码
不同学习率对收敛的影响:(图片来源:csn231n)

此外,学习率会影响模型收敛到局部最小值的速度(也就是达到最佳的精度)。因此,在正确的方向做出正确的选择,意味着我们只需更少的时间来训练模型。

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

AI 前线:目前深度学习使用的都是一阶收敛算法:梯度下降法。不管有多少自适应的优化算法,本质上都是对梯度下降法的各种变形。故初始学习率对深层网络的收敛起着决定性的作用。

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

在“训练神经网络的循环学习率(Cyclical Learning Rates (CLR)for Training Neural Networks)”[4] 的第 3.3 节中。Leslie N. Smith 认为,通过在每次迭代中以非常低的学习率来增加(线性或指数)的方式训练模型,可以估计好的学习率。

AI 前线:周期性学习率(Cyclical Learning Rates,CLR),即学习率退火与热重启,最初由 Smith 于 2015 年首次提出。这是一种新的学习率方法,和以前的不同,或者固定(fixed)或者单调递减。要使用 CLR,需指定这三个参数:max_lr、base_lr、stepsize。

复制代码
学习率在每个小批量之后增加

如果我们在每次迭代中记录学习率和训练损失,然后据此绘出曲线图;我们将会看到,随着学习率的提高,将会有一个损失停止下降并开始增加的点。在实践中,理想情况下,学习率应该是在左图的最低点(如下图所示)。在该例中为 0.001 到 0.01 之间。

以上看起来很有用。我该如何开始使用它?

目前,它被作为 fast.ai 深度学习库的一个函数来支持。由 Jeremy Howard 开发,是用来抽象 PyTorch 深度学习框架的一种方式,就像 Keras 是对 TensorFlow 框架的抽象。

AI 前线: fast.ai 深度学习库是 fast.ai 基于 PyTorch 的基础上创建的自有软件库,并且他们认为,这将有助于更加清晰地展示深度学习的概念,同时有助于实现最佳编码。采用 Apache 2.0 许可证,可免费使用。

只需输入以下命令,就可以在训练神经网络之前找到最佳学习率。

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

精益求精

在这个关键时刻,我们已经讨论了学习率的全部内容和它的重要性,以及我们如何在开始训练模型时系统地达到最佳的使用价值。

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

一般看法

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

然而,随着梯度逐渐趋于稳定时,训练损失也变得难以改善。在 [3] 中,Dauphin 等人认为,最大限度地减少损失的难度来自于鞍点,而非局部极小值。

AI 前线:鞍点是梯度接近于 0 的点,在误差曲面中既不是最大值也不是最小值的平滑曲面,则一般结果表现为性能比较差;如果该驻点是局部极小值,那么表现为性能较好,但不是全局最优值。

复制代码
误差曲面中的鞍点。鞍点是函数的导数变为零但点不是所有轴上的局部极值的点。(图片来源:safaribooksonline)

那么我们该如何摆脱呢?

有几个选项我们可以考虑。一般来说,从 [1] 引用一句:

……而不是使用一个固定值的学习率,并随着时间的推移而降低,如果训练不会改善我们的损失,我们将根据一些循环函数 _f_ 来改变每次迭代的学习率。每个周期的迭代次数都是固定的。这种方法让学习率在合理的边界值之间循环变化。这有助于解决问题,因为如果我们被困在鞍点上,提高学习率可以更快速地穿越鞍点。

在 [2] 中,Leslie 提出了一种“Triangular”的方法,在每次迭代之后,学习率都会重新开始。

复制代码
Leslie N. Smith 提出的“Triangular”和“Triangular2”循环学习率的方法。在左边的图上,minmax lr 保持不变。在右边,每个周期之后的差异减半。

另一种同样受欢迎的方法是由 Loshchilov 和 Hutter 提出的热重启的随机梯度下降法(Stochastic Gradient Descent with Warm Restarts,SGDR)[6]。这种方法主要利用余弦函数作为循环函数,并在每个周期的最大值重新开始学习率。“热重启”一词源于这样的一个事实:当学习率重新开始的时候,并不是从头开始,而是来自模型在上一步收敛的参数开始 [7]。

AI 前线:热重启后的初始高学习率用于基本上将参数从它们先前收敛的最小值弹射到不同的损失表面。根据经验,热重启的随机梯度下降法需要的时间比学习率退火要少 2~4 倍,且能达到相当或更好的性能。

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

复制代码
SGDR 图,学习率与迭代。

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

复制代码
比较固定学习率和循环学习率(图片来源:ruder.io

除了节省时间外,研究还表明,使用这些方法往往可以提高分类准确性,而无需进行调优,而且可以在更少的迭代次数内完成。


迁移学习(Transfer Learning)中的学习率

在 fast.ai 课程中,在解决 AI 问题时,非常重视利用预先训练的模型。例如,在解决图像分类问题时,教授学生如何使用预先训练好的模型,如 VGG 或 Resnet50,并将其连接到想要预测的任何图像数据集。

总结如何在 fast.ai 中完成模型构建(注意该程序不要与 fast.ai 深度学习库混淆),下面是我们通常采取的几个步骤 [8]:

1. 启用数据增强,precompute=True。
2. 使用 lr_find()查找最高的学习率,在此情况下,损失仍在明显改善。
3. 训练最后一层从预计算激活 1~2 个轮数。
4. 在 cycle_len=1 的情况下训练最后一层数据增加(即 precompute=False)2~3 个轮数。
5. 解除所有层的冻结。
6. 将较早的层设置为比下一个较高层低 3~10 倍的学习率。
7. 再次使用lr_find()
8. 使用 cycle_mult=2 训练完整网络,直到过度拟合。

从上面的步骤中,我们注意到第 2 步、第 5 步和第 7 步关注了学习率。在这篇文章的前半部分,我们已经基本讨论了涵盖了上述步骤中的第 2 项——我们在这里讨论了如何在训练模型之前得出最佳学习率。

AI 前线:轮数,epoch,即对所有训练数据的一轮遍历。

在接下来的部分中,我们通过使用 SGDR 来了解如何通过重新开始学习速率来减少训练时间和提高准确性,以避免梯度接近于 0 的区域。

在最后一节中,我们将重点讨论差分学习,以及它是如何被用来在训练模型与预先训练的模型相结合时确定学习率的。

什么是差分学习?

这是一种在训练期间为网络中的不同层设置不同的学习率的方法。这与人们通常如何配置学习率相反,即在训练期间在整个网络中使用相同的速率。

这是我为什么喜欢 Twitter 的原因之一——可以直接从作者本人得到答案。

在写这篇文章的时候,Jeremy 和 Sebastian Ruder 发表了一篇论文,深入探讨了这个话题。所以我估计差分学习率现在有一个新的名字:判别式微调(discriminative fine-tuning)。 :)

AI 前线:判别式微调对较底层进行微调以调到一个相较于较高层较低的程度,从而保留通过语言建模所获得的的知识。它可以避免微调过程中产生严重的遗忘。

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

复制代码
差分学习率的 CNN 样本。图片来自 [3]

这种配置方法背后的直觉是,最初的几层通常包含数据的非常细粒度的细节,如线条和边缘——我们通常不希望改变太多,并且保留它的信息。因此,没有太多的需要去大量改变它们的权重。

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

与其他微调方法相比,它表现如何?

在 [9] 中,有人认为,对整个模型进行微调的代价太大,因为有些模型可能有 100 多个层。因此,人们通常做的是一次对模型进行微调。

但是,这就引入了顺序的要求,妨碍了并行性,并且需要多次通过数据集,从而导致对小数据集的过度拟合。

也已经证明 [9] 中引入的方法能够在不同的 NLP 分类任务中提高精度和降低错误率(如下图所示):

复制代码
取自 [9] 的结果

参考资料

[0] Understanding Learning Rates and How It Improves Performance in Deep Learning

[1] Improving the way we work with learning rate. [2] The Cyclical Learning Rate technique. [3] Transfer Learning using differential learning rates. [4] Leslie N. Smith. Cyclical Learning Rates for Training Neural Networks. [5] Estimating an Optimal Learning Rate for a Deep Neural Network [6] Stochastic Gradient Descent with Warm Restarts [7] Optimization for Deep Learning Highlights in 2017 [8] Lesson 1 Notebook, fast.ai Part 1 V2 [9] Fine-tuned Language Models for Text Classification

感谢陈利鑫对本文的审校。

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2018-03-18 18:085218
用户头像

发布了 368 篇内容, 共 170.3 次阅读, 收获喜欢 939 次。

关注

评论

发布
暂无评论
发现更多内容

浅谈 Spring 如何解决 Bean 的循环依赖问题

做梦都在改BUG

Java spring 循环依赖

真的香!腾讯SpringBoot高阶笔记,限时开源48小时

程序知音

Java 微服务 编程语言 springboot java架构

一个神奇的需求:doc批量转docx,1行Python代码实现

程序员晚枫

Python word 自动化办公

云计算时代前端如何保证开源代码的安全性

京东科技开发者

前端 安全 京东云 京东科技 企业号 4 月 PK 榜

JSF预热功能的实践与探索

京东科技开发者

京东云 jsf 企业号 4 月 PK 榜

阿里CTO最新分享神仙级“多线程手册”全套笔记,涵盖了多线程相关所有知识点

开心学Java

Java 线程 多线程 阿里

设计模式之美--经常被用错的KISS、YAGNI原则

GalaxyCreater

设计模式

深度学习基础入门篇[一]:神经元简介、单层多层感知机、距离计算方法式、相似度函数

汀丶人工智能

人工智能 机器学习 深度学习 多层感知机

一路披荆斩棘腾讯6面面经(已拿offer)大厂远没想象中的难

小小怪下士

Java 程序员 面试 后端

月内狂飙 50%的 ZBC ,连续登顶Solana 链交易量排行榜

威廉META

Service进阶

二哈侠

service intentservice 轮询

不敲一行代码,用ChatGPT开发App

FN0

移动开发 ChatGPT

业务防资损,质量保障的第一要务!

老张

业务价值 交付质量 防资损

新一代分布式任务调度框架

程序员大彬

Java 面试

肝完阿里最新Java并发编程全优笔记,我成功晋升公司架构组

程序员小毕

Java 源码 程序员 面试 并发编程

创业公司如何不沦为OpenAI“死侍军团”:训练小众数据,服务特定用户

B Impact

Python数据分析库介绍及引入惯例

timerring

Python pandas

Django笔记一之运行系统、创建视图并访问

Hunter熊

django

【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(上)

洛神灬殇

4月月更 时间轮(TimeWheel) 算法指南 技术调整

5.5G,运营商能接受吗?

脑极体

5.5G

负载均衡算法的实现

王玉川

c++ 负载均衡 高可用 高并发 一致性哈希

为 NGINX 配置免费的 Let’s Encrypt SSL/TLS 证书

NGINX开源社区

火了!北大学霸爆肝3个月的算法小抄完整笔记,GitHub疯狂转发

做梦都在改BUG

Java 数据结构 算法

前端面试实录HTML篇

控心つcrazy

html 面试 前端 HTML5, CSS3

阿里内部最新发布的并发图册+JDK源码速成笔记,终于解脱束缚了

开心学Java

Java jdk 高并发

阿里大佬力荐K8s项目实战笔记!图文并茂带你深度解析Kubernetes

做梦都在改BUG

Java Kubernetes k8s

卓越工程之开发过程管理

agnostic

卓越工程

熬夜肝完! 阿里P8的Java进阶知识典藏版,我从18K飙到30K

程序知音

Java 编程语言 java面试 java架构 Java面试题

细节拉满,80 张图带你一步一步推演 slab 内存池的设计与实现

bin的技术小屋

内存管理 Linux Kenel 内核 内存池

涨薪跳板! 2023阿里突击版Java面试宝典

程序知音

Java 编程语言 java面试 java架构 后端技术

深入理解MySQL索引底层数据结构

京东科技开发者

MySQL 京东云 京东技术 企业号 4 月 PK 榜

了解学习率及其如何提高深度学习的性能_语言 & 开发_刘志勇_InfoQ精选文章