给深度学习神经网络从业者的建议

鉴于开源库的广泛采用,深度学习神经网络的定义和训练相对简单。

然而,神经网络的配置和训练仍然具有挑战性。

在他的2012年预印本和热门图书《神经网络:实用技巧》(Neural Networks: Tricks of the Trade) 的一章中,深度学习领域的奠基人之一 Yoshua Bengio 撰写了题为《基于梯度的深度架构训练的实用建议》(Practical Recommendations for Gradient-Based Training of Deep Architectures) 的论文,提供了配置和调整神经网络模型的实用建议。

在这篇文章中,您将逐步阅读这篇长而有趣的论文,并为现代深度学习从业者挑选出最相关的技巧和窍门。

阅读本文后,你将了解:

  • 包括预训练和自编码器在内的深度学习复兴的早期基础。
  • 神经网络超参数初始配置的建议。
  • 如何有效地调整神经网络超参数以及更有效地调整模型的策略。

用我的新书《更好的深度学习》来启动你的项目,书中包含分步教程和所有示例的 Python 源代码文件

让我们开始吧。

Practical Recommendations for Deep Learning Neural Network Practitioners

深度学习神经网络从业者的实用建议
图片由 Susanne Nilsson 提供,保留部分权利。

概述

本教程分为五个部分;它们是:

  1. 从业者必读
  2. 论文概述
  3. 深度学习的开端
  4. 通过梯度下降学习
  5. 超参数建议

对从业者的建议

2012年,热门实用书籍《神经网络:实用技巧》(Neural Networks: Tricks of the Trade) 出版了第二版。

第一版于1999年出版,包含17章(每章由不同的学者和专家撰写),介绍如何充分利用神经网络模型。更新的第二版增加了13章,其中包括 Yoshua Bengio 撰写的重要一章(第19章),题为《基于梯度的深度架构训练的实用建议》(Practical Recommendations for Gradient-Based Training of Deep Architectures)。

第二版出版之时,正值人们对神经网络重新产生兴趣,并开启了“深度学习”的时代。Yoshua Bengio 的章节很重要,因为它为开发神经网络模型提供了建议,包括当时非常现代的深度学习方法的细节。

尽管该章节可以作为第二版的一部分阅读,但 Bengio 也将该章节的预印本发布到 arXiv 网站,可在此处访问:

该章节也很重要,因为它为四年后成为事实上的深度学习教科书《深度学习》(Deep Learning) 奠定了宝贵的基础,Bengio 也是该书的合著者。

该章节(我以后将其称为论文)是所有神经网络从业者的必读材料。

在这篇文章中,我们将逐步阅读论文的每个部分,并指出一些最突出的建议。

想要通过深度学习获得更好的结果吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

论文概述

这篇论文的目的是为从业者提供开发神经网络模型的实用建议。

神经网络模型种类繁多,从业者类型也很多,因此目标很广泛,建议不针对特定类型的神经网络或预测建模问题。这很好,因为我们可以在我们的项目上广泛应用这些建议,但也很令人沮丧,因为没有给出文献中的具体示例或案例研究。

这些建议的重点是模型超参数的配置,特别是与随机梯度下降学习算法相关的超参数。

本章旨在作为一份实用指南,提供一些最常用超参数的建议,尤其是在基于反向传播梯度和梯度优化的学习算法背景下。

这些建议是在深度学习领域兴起之初提出的,当时现代方法和快速GPU硬件促进了比以往任何时候都更深、能力更强的网络的发展。Bengio 将这场复兴追溯到2006年(撰写本文的六年前)以及贪婪分层预训练方法的发展,这些方法后来(在这篇论文撰写之后)被ReLU、Dropout、BatchNorm和其他有助于开发非常深层模型的广泛使用所取代。

2006年的深度学习突破,其核心是利用无监督学习,通过在特征层次结构的每个级别提供局部训练信号来帮助学习内部表示。

该论文分为六个主要部分,其中第三部分是阅读重点,主要关注超参数配置的建议。论文的完整目录如下。

  • 摘要
  • 1 引言
    • 1.1 深度学习与贪婪分层预训练
    • 1.2 去噪自编码器和收缩自编码器
    • 1.3 在线学习与泛化误差优化
  • 2 梯度
    • 2.1 梯度下降与学习率
    • 2.2 梯度计算与自动微分
  • 3 超参数
    • 3.1 神经网络超参数
      • 3.1.1 近似优化的超参数
    • 3.2 模型和训练准则的超参数
    • 3.3 手动搜索和网格搜索
      • 3.3.1 超参数探索的一般指导
      • 3.3.2 坐标下降和多分辨率搜索
      • 3.3.3 自动化和半自动化网格搜索
      • 3.3.4 分层超参数优化
    • 3.4 超参数的随机采样
  • 4 调试与分析
    • 4.1 梯度检查与受控过拟合
    • 4.2 可视化与统计
  • 5 其他建议
    • 5.1 多核机器、BLAS和GPU
    • 5.2 稀疏高维输入
    • 5.3 符号变量、嵌入、多任务学习和多关系学习
  • 6 未解决问题
    • 6.1 训练更深层架构的额外难度
    • 6.2 自适应学习率和二阶方法
    • 6.3 结论

我们不会触及每个部分,而是重点关注论文的开头部分,特别是关于超参数和模型调优的建议。

深度学习的开端

引言部分花了一些时间介绍深度学习的开端,如果将其视为该领域的历史快照,则会非常引人入胜。

当时,深度学习的复兴是由神经网络模型的发展推动的,这些模型比以前可以使用更多层,这基于贪婪分层预训练和通过自编码器进行表示学习等技术。

训练深度神经网络最常用的方法之一是基于贪婪分层预训练。

这种方法不仅重要,因为它允许开发更深层的模型,而且其无监督形式允许使用未标记的示例,例如半监督学习,这也是一个突破。

特征学习和深度学习的另一个重要动机是,它们可以用未标记的示例完成……

因此,重用(字面上的重用)是一个主要的主题。

重用的概念解释了分布式表示的力量,也是深度学习背后理论优势的核心。

尽管具有足够容量的单层或两层神经网络在理论上可以近似任何函数,但他温和地提醒我们,深度网络为近似更复杂的函数提供了计算上的捷径。这是一个重要的提醒,有助于激发深度模型的发展。

理论结果清楚地确定了某些函数族,在这些函数族中,深度表示可以比不够深的表示效率高出指数级。

本文花时间逐步介绍了“深度学习”的两个主要突破:贪婪分层预训练(包括有监督和无监督)和自编码器(包括去噪和对比)。

第三个突破,RBM,则留给该书另一章由该方法的开发者 Hinton 讨论。

  • 受限玻尔兹曼机(RBM)。
  • 贪婪分层预训练(无监督和有监督)。
  • 自编码器(去噪和对比)。

尽管是里程碑,但这些技术在今天的深度学习发展中(六年之后)都没有得到广泛的优先使用,除了自编码器之外,也没有像以前那样得到积极研究。

通过梯度下降学习

第二部分提供了梯度和梯度学习算法的基础,这是用于将神经网络权重拟合到训练数据集的主要优化技术。

这包括批量梯度下降和随机梯度下降之间的重要区别,以及通过小批量梯度下降进行的近似,如今所有这些都简称为随机梯度下降。

  • 批量梯度下降。梯度是使用训练数据集中的所有示例估计的。
  • 小批量梯度下降。梯度是使用训练数据集中样本的子集估计的。
  • 随机(在线)梯度下降。梯度是使用训练数据集中每个单一模式估计的。

小批量变体被认为是实现随机梯度下降所提供的收敛速度,同时获得批量梯度下降所提供的改进的误差梯度估计的一种方法。

较大的批量大小会减慢收敛速度。

另一方面,随着 B [批量大小] 的增加,每次计算的更新次数减少,这会减慢收敛速度(就误差与执行的乘加操作次数而言),因为在相同的计算时间内可以进行的更新次数较少。

较小的批量大小由于在梯度估计中引入统计噪声而具有正则化效果。

……较小的 B [批量大小] 值可能会受益于参数空间中更多的探索以及由于梯度估计器中注入的“噪声”而形成的一种正则化形式,这可能解释了有时在较小 B 值下观察到的更好的测试结果。

这一时期也伴随着自动微分在神经网络模型开发中的引入和更广泛的采用。

梯度可以手动计算,也可以通过自动微分计算。

鉴于 Bengio 参与了 Theano Python 数学库pylearn2 深度学习库的开发,这一点尤其引起他的兴趣。这两个库现已停用,可能已被 TensorFlowKeras 分别取代。

手动实现神经网络的微分很容易出错,而且错误难以调试,会导致性能不佳。

当使用手动微分实现梯度下降算法时,结果往往是冗长、脆弱且缺乏模块化的代码——从软件工程的角度来看,这些都是不好的事情。

自动微分被描绘成一种更健壮的开发神经网络的方法,即将其表示为数学运算图,每个运算都知道如何微分,并且可以符号化定义。

更好的方法是根据对象来表达流图,这些对象模块化地计算输入到输出的方式,以及计算梯度下降所需的偏导数的方式。

这种基于图的方法在定义模型方面的灵活性,以及计算误差导数时错误可能性降低的特点,意味着这种方法已经成为现代开源神经网络库的标准,至少在底层数学库中是如此。

超参数建议

论文的主要重点是控制模型在随机梯度下降下的收敛性和泛化能力的超参数配置。

使用验证数据集

本节首先强调了使用独立于训练集和测试集的验证数据集来调整模型超参数的重要性。

对于任何对学习器有效容量有影响的超参数,根据样本外数据(训练集之外),例如验证集性能、在线误差或交叉验证误差来选择其值更有意义。

并强调不应将验证数据集包含在模型性能评估中。

一旦某些样本外数据已被用于选择超参数值,它就不能再用于获得泛化性能的无偏估计器,因此通常使用测试集(或者在数据集较小的情况下使用双重交叉验证)来估计纯学习算法(其中超参数选择隐藏在其中)的泛化误差。

交叉验证通常不用于神经网络模型,因为它们可能需要数天、数周甚至数月才能训练。然而,在可以使用交叉验证的较小数据集上,建议使用双重交叉验证技术,即在每个交叉验证折叠内执行超参数调整。

双重交叉验证递归地应用交叉验证的思想,使用外部循环交叉验证来评估泛化误差,然后在每个外部循环拆分的训练子集(即,再次将其拆分为训练和验证折叠)内部应用内部循环交叉验证,以便为该拆分选择超参数。

学习超参数

接着介绍了一系列学习超参数,并提供了相关建议。

这一系列的超参数包括

  • 初始学习率。权重更新的比例;0.01 是一个不错的开始。
  • 学习率计划。学习率随时间递减;1/T 是一个不错的开始。
  • 小批量大小。用于估计梯度的样本数量;32 是一个不错的开始。
  • 训练迭代次数。权重更新的次数;设置大一些,并使用早期停止。
  • 动量。使用之前权重更新的历史;设置大一些(例如 0.9)。
  • 特定于层的超参数。可能,但很少使用。

学习率被认为是调整最重要的参数。尽管建议的起始值为 0.01,但仍需要根据特定数据集和模型进行调整。

这通常是唯一最重要的超参数,并且始终应该确保它已被调整 […] 默认值 0.01 通常适用于标准多层神经网络,但完全依赖此默认值是愚蠢的。

他甚至说,如果只能调整一个参数,那么就是学习率。

如果只有时间优化一个超参数并且使用随机梯度下降,那么这就是值得调整的超参数。

批量大小被描述为学习速度的控制,而不是关于调整测试集性能(泛化误差)的。

理论上,这个超参数应该影响训练时间,而不是太多地影响测试性能,因此它可以在其他超参数(除了学习率)已被选择之后,通过比较训练曲线(训练和验证误差与训练时间量)来独立优化。

模型超参数

接下来介绍了模型超参数,并再次提供了相关建议。

它们是

  • 节点数。控制模型的容量;使用带正则化的大模型。
  • 权重正则化。惩罚具有大权重的模型;通常尝试 L2,对于稀疏性尝试 L1。
  • 激活正则化。惩罚具有大激活的模型;对于稀疏表示尝试 L1。
  • 激活函数。用作隐藏层节点输出;使用 S 型函数(Logistic 和 Tang)或整流器(现在是标准)。
  • 权重初始化。优化过程的起点;受激活函数和前一层大小的影响。
  • 随机种子。优化过程的随机性;对多次运行的模型进行平均。
  • 预处理。在建模前准备数据;至少标准化并去除相关性。

配置层中的节点数具有挑战性,可能是初学者最常问的问题之一。他建议在每个隐藏层中使用相同数量的节点可能是一个好的起点。

在一项大型比较研究中,我们发现对所有层使用相同大小通常比使用递减大小(金字塔形)或递增大小(倒金字塔形)效果更好或相同,但当然这可能取决于数据。

他还建议为第一个隐藏层使用过完备配置。

对于我们从事的大多数任务,我们发现过完备(大于输入向量)的第一个隐藏层比欠完备的层效果更好。

鉴于当时对逐层训练和自编码器的关注,表示的稀疏性(隐藏层的输出)是一个重点。因此,推荐使用激活正则化,这在大型编码器-解码器模型中可能仍然有用。

稀疏表示可能是有利的,因为它们鼓励表示能够解缠结底层表示因子。

当时,线性整流激活函数才刚刚开始使用,尚未广泛采用。如今,使用整流器(ReLU)已成为标准,因为使用它的模型轻松超越了使用 Logistic 或双曲正切非线性函数的模型。

调整超参数

默认配置对于大多数问题中的大多数神经网络都表现良好。

然而,为了在给定数据集上充分利用给定模型,超参数调整是必需的。

调整超参数可能具有挑战性,这既是因为所需的计算资源,也因为验证数据集容易过拟合,导致误导性结果。

必须将超参数选择视为一种困难的学习形式:既存在一个优化问题(寻找产生低验证误差的超参数配置),又存在一个泛化问题:在优化验证性能后,对预期的泛化存在不确定性,并且可能会对验证误差过拟合,并在比较许多超参数配置时获得乐观偏差的性能估计器。

为一个模型调整一个超参数并绘制结果通常会得到一个 U 形曲线,显示出性能不佳、良好性能,然后又回到性能不佳的模式(例如最小化损失或误差)。目标是找到“U”的底部。

问题是,许多超参数相互作用,而且“U”的底部可能存在噪声。

尽管我们期望近似呈 U 形曲线(当只考虑单个超参数,其他超参数固定时),但这条曲线也可能存在噪声变化,部分原因是使用了有限的数据集。

为了辅助这项搜索,他接着提供了在调整模型超参数时需要考虑的三个有价值的通用技巧:

  • 边界上的最佳值。如果在搜索区间的边缘找到了一个好值,请考虑扩大搜索范围。
  • 考虑值的尺度。考虑在对数尺度上搜索,至少一开始是这样(例如 0.1、0.01、0.001 等)。
  • 计算考虑因素。考虑牺牲结果的精度以加速搜索。

提出了三种系统的超参数搜索策略

  • 坐标下降。一次只调整一个超参数。
  • 多分辨率搜索。迭代地缩小搜索区间。
  • 网格搜索。定义一个 N 维值网格,然后依次测试每个值。

这些策略可以单独使用,甚至可以组合使用。

网格搜索也许是最广为人知和广泛使用的模型超参数调整方法。它是穷举搜索,但可并行化,利用廉价的云计算基础设施可以发挥其优势。

与许多其他优化策略(如坐标下降)相比,网格搜索的优势在于它完全可并行化。

通常,通过迭代网格搜索重复该过程,结合多分辨率和网格搜索。

通常,一次网格搜索是不够的,从业者倾向于进行一系列网格搜索,每次都根据之前获得的结果调整所考虑值的范围。

他还建议让人工参与,以观察错误并利用模式识别来识别趋势并改变搜索空间的形状。

人类在执行超参数搜索方面可以做得很好,并且让人工参与的另一个优点是它可以帮助检测学习算法的错误或不想要或意外的行为。

然而,尽可能实现自动化很重要,以确保该过程在未来新的问题和模型中可重复。

网格搜索是穷举且缓慢的。

网格搜索方法寻找良好超参数配置的一个严重问题是,它的扩展性与所考虑的超参数数量呈指数级恶化。

他建议使用随机采样策略,这已被证明是有效的。每个超参数的区间可以均匀搜索。这种分布可以通过包含先验(例如选择合理的默认值)来偏置。

随机采样的思想是用随机(通常是均匀的)采样代替规则网格。每个测试的超参数配置都是通过从先验分布(通常在对数域中,在感兴趣的区间内均匀分布)中独立采样每个超参数来选择的。

论文最后提出了更一般的建议,包括调试学习过程的技术、使用 GPU 硬件加速训练的方法以及仍然存在的开放问题。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

总结

在这篇文章中,您发现了 Yoshua Bengio 2012年论文《基于梯度的深度架构训练的实用建议》(Practical Recommendations for Gradient-Based Training of Deep Architectures) 中重要的建议、技巧和窍门。

您读过这篇论文吗?您有什么想法?
在下面的评论中告诉我。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

今天就开发更好的深度学习模型!

Better Deep Learning

更快地训练,减少过拟合,以及集成方法

...只需几行python代码

在我的新电子书中探索如何实现
更好的深度学习

它提供关于以下主题的自学教程
权重衰减批量归一化dropout模型堆叠等等...

为你的项目带来更好的深度学习!

跳过学术理论。只看结果。

查看内容

对《深度学习神经网络从业者的建议》的8条回复

  1. Jam 2019年2月25日 下午5:19 #

    你好,
    我认为以下定义被互换了

    “随机(在线)梯度下降。梯度是使用训练数据集中的样本子集估计的。
    小批量梯度下降。梯度是使用训练数据集中每个单一模式估计的。”

    一如既往的精彩文章,Jason,谢谢。

  2. Ozgur 2019年2月26日 上午8:30 #

    我认为,“随机(在线)梯度下降”和“小批量梯度下降”的标题最好互换。

  3. Oli 2020年10月22日 上午4:11 #

    你好 Jason,有没有关于使用 TPE 或 Bayes 来优化神经网络超参数的优秀文献?

    我使用 Hyperopt 在 XGBoost 上取得了很大的成功,但将其与 Tensorflow 2.3 结合使用时,由于弃用以及 hyperopt、sklearn 和 tensorflow 之间的不兼容性,导致了很多麻烦。

    谢谢!

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。