tuning_playbook - 一本用于系统地最大化深度学习模型性能的手册。

Created at: 2023-01-19 07:32:32
Language:
License: NOASSERTION

深度学习调优行动手册

这不是官方支持的 Google 产品。

瓦伦·戈德伯尔、乔治·达尔、贾斯汀·吉尔默、克里斯托弗·沙鲁、扎卡里·纳多

† 谷歌研究,大脑团队

‡ 哈佛大学

目录

此文档适用于谁?

本文档面向对最大化深度学习模型性能感兴趣的工程师和研究人员(个人和团队)。我们假设机器学习和深度学习概念的基本知识。

我们的重点是超参数调优的过程。我们涉及深度学习训练的其他方面,例如管道实现和优化,但我们对这些方面的处理并不打算完整。

我们假设机器学习问题是一个监督学习问题,或者看起来很像一个问题(例如自我监督)。也就是说,本文档中的一些规定也可能适用于其他类型的问题。

为什么要调整剧本?

目前,要让深度神经网络在实践中很好地工作,需要大量的辛劳和猜测。更糟糕的是,人们用来通过深度学习获得良好结果的实际配方很少被记录下来。论文掩盖了导致最终结果的过程,以呈现一个更清晰的故事,而从事商业问题的机器学习工程师很少有时间退后一步并概括他们的过程。教科书倾向于避开实际指导,优先考虑基本原则,即使其作者在应用工作中具有必要的经验,可以提供有用的建议。在准备创建本文档时,我们找不到任何全面的尝试来实际解释如何通过深度学习获得良好的结果。相反,我们在博客文章和社交媒体上发现了一些建议片段,从研究论文附录中窥视的技巧,偶尔关于一个特定项目或管道的案例研究,以及很多混乱。深度学习专家和使用表面相似方法的不太熟练的从业者所取得的结果之间存在巨大鸿沟。与此同时,这些专家欣然承认,他们所做的一些事情可能没有充分的理由。随着深度学习的成熟并对世界产生更大的影响,社区需要更多的资源来涵盖有用的食谱,包括所有对获得良好结果至关重要的实用细节。

我们是一个由五名研究人员和工程师组成的团队,他们在深度学习领域工作了很多年,其中一些人早在2006年就已经工作了。我们已经将深度学习应用于从语音识别到天文学的所有问题,并在此过程中学到了很多东西。本文档源于我们自己训练神经网络、教授新的机器学习工程师以及就深度学习实践向同事提供建议的经验。尽管看到深度学习从少数学术实验室实践的机器学习方法转变为为数十亿人使用的产品提供动力的技术是令人欣慰的,但深度学习作为一门工程学科仍处于起步阶段,我们希望本文档鼓励其他人帮助系统化该领域的实验协议。

本文档是在我们想具体化我们自己的深度学习方法时出现的,因此它代表了作者在撰写本文时的观点,而不是任何客观事实。我们自己在超参数调优方面的挣扎使其成为我们指导的特别重点,但我们也涵盖了我们在工作中遇到的其他重要问题(或看到出错)。我们的目的是让这项工作成为一份活的文件,随着我们信仰的变化而成长和发展。例如,关于调试和缓解培训失败的材料,我们两年前就不可能写出来,因为它是基于最近的结果和正在进行的调查。不可避免地,我们的一些建议将需要更新,以考虑新的结果和改进的工作流程。我们不知道最佳的深度学习配方,但在社区开始写下和讨论不同的程序之前,我们不能指望找到它。为此,我们鼓励发现我们的建议有问题的读者提出替代建议以及令人信服的证据,以便我们更新剧本。我们也希望看到可能有不同的建议的替代指南和剧本,以便我们可以作为一个社区努力实现最佳实践。最后,任何标有🤖表情符号的部分都是我们想做更多研究的地方。只有在尝试编写这本剧本之后,才完全清楚在深度学习从业者的工作流程中可以找到多少有趣和被忽视的研究问题。

启动新项目的指南

我们在调优过程中做出的许多决定可以在项目开始时做出一次,并且只有在情况发生变化时偶尔重新审视。

我们下面的指导做出以下假设:

  • 问题制定、数据清理等基本工作已经完成得足够多,因此花时间在模型架构和训练配置上是有意义的。
  • 已经设置了一个进行训练和评估的管道,并且可以轻松地为各种感兴趣的模型执行训练和预测作业。
  • 已选择并实施了适当的指标。这些应尽可能代表在部署环境中要测量的内容。

选择模型体系结构

摘要:启动新项目时,请尝试重用已经工作的模型。

  • 选择一个完善的常用模型架构来首先开始工作。以后始终可以构建自定义模型。
  • 模型架构通常具有各种超参数,用于确定模型的大小和其他细节(例如层数、层宽、激活函数类型)。
  • 如果可能的话,试着找一篇论文,尽可能接近手头的问题,并重现该模型作为起点。

选择优化器

摘要:从手头问题类型的最流行的优化器开始。

  • 在所有类型的机器学习问题和模型架构中,没有优化器是“最好的”。即使只是比较优化器的性能也是一项艰巨的任务。🤖
  • 我们建议坚持使用成熟的、流行的优化器,尤其是在启动新项目时。
    • 理想情况下,选择用于相同类型问题的最受欢迎的优化器。
  • 准备好关注所选优化器的*所有*超参数。
    • 具有更多超参数的优化器可能需要更多调优工作才能找到最佳配置。
    • 这在项目的开始阶段尤其重要,当我们想找到各种其他超参数(例如架构超参数)的最佳值,同时将优化器超参数视为令人讨厌的参数时。
    • 在项目的初始阶段,最好从更简单的优化器(例如,具有固定动量的 SGD 或具有固定 $\epsilon$、$\beta_{1}$ 和 $\beta_{2}$)的 Adam 开始,稍后切换到更通用的优化器。
  • 我们喜欢的成熟优化器包括(但不限于):

选择批量大小

摘要:批大小控制训练速度,不应用于直接调整验证集性能。通常,理想的批大小将是可用硬件支持的最大批大小。

  • 批量大小是确定训练时间和计算资源消耗的关键因素。
  • 增加批量大小通常会减少训练时间。这可能是非常有益的,因为它,例如:
    • 允许在固定的时间间隔内更彻底地调整超参数,从而可能产生更好的最终模型。
    • 减少开发周期的延迟,允许更频繁地测试新想法。
  • 增加批大小可能会减少、增加或不更改资源消耗。
  • 不应将批大小视为验证集性能的可调超参数。

确定可行的批量大小并估算训练吞吐量

[点击展开]
  • 对于给定的模型和优化器,可用硬件通常支持一系列批大小。限制因素通常是加速器内存。
  • 遗憾的是,如果不运行或至少编译完整的训练程序,就很难计算出哪些批大小适合内存。
  • 最简单的解决方案通常是以不同的批量大小运行训练作业(例如,增加 2 的幂)进行少量步骤,直到其中一个作业超过可用内存。
  • 对于每个批量大小,我们应该训练足够长的时间,以获得训练吞吐量的可靠估计

训练吞吐量 =(# 每秒处理的示例)

或者,等效地,每一步的时间

每步时间 =(批量大小)/(训练吞吐量)

  • 当加速器尚未饱和时,如果批大小加倍,则训练吞吐量也应翻倍(或至少接近两倍)。等效地,随着批大小的增加,每步的时间应该是恒定的(或至少几乎恒定的)。
  • 如果不是这种情况,则训练管道存在瓶颈,例如计算节点之间的 I/O 或同步。在继续之前,这可能值得诊断和更正。
  • 如果训练吞吐量仅增加到某个最大批大小,则即使硬件支持更大的批大小,我们也应仅考虑最大批大小的批大小。
    • 使用较大批大小的所有好处都假设训练吞吐量增加。如果没有,请修复瓶颈或使用较小的批量大小。
    • 梯度累积模拟的批大小大于硬件可以支持的批大小,因此不提供任何吞吐量优势。在应用工作中通常应避免使用。
  • 每次更改模型或优化器时,可能需要重复这些步骤(例如,不同的模型体系结构可能允许更大的批处理大小以容纳内存)。

选择批量大小以最大程度地减少训练时间

[点击展开]

训练时间 =(每步时间)x(总步数)

  • 对于所有可行的批量大小,我们通常可以认为每步的时间大致恒定。当并行计算没有开销并且所有训练瓶颈都已诊断和纠正时,情况确实如此(有关如何识别训练瓶颈,请参阅上一节)。实际上,增加批大小通常至少会产生一些开销。
  • 随着批大小的增加,达到固定性能目标所需的总步骤数通常会减少(前提是在更改批大小时重新调整所有相关超参数;沙鲁等人,2018 年)。
    • 例如,将批量大小加倍可能会使所需的步骤总数减半。这称为完美缩放
    • 完美的扩展适用于所有批量大小,直至关键批量大小,超过该大小即可实现收益递减。
    • 最终,增加批量大小不再减少训练步骤的数量(但永远不会增加它)。
  • 因此,最小化训练时间的批大小通常是仍能减少所需训练步骤数的最大批大小。
    • 此批大小取决于数据集、模型和优化器,除了为每个新问题通过实验找到它之外,如何计算它是一个悬而未决的问题。🤖
    • 比较批次大小时,请注意示例预算/纪元预算(在固定训练示例演示数量的同时运行所有实验)和步骤预算(在固定训练步骤数的情况下运行所有实验)之间的区别。
      • 将批量大小与 epoch 预算进行比较只能探测完美的扩展方案,即使较大的批量大小仍可能通过减少所需的训练步骤数量来提供有意义的加速。
    • 通常,可用硬件支持的最大批大小将小于关键批大小。因此,一个好的经验法则(无需运行任何实验)是使用尽可能大的批量大小。
  • 如果最终会增加训练时间,那么使用更大的批量大小是没有意义的。

选择批量大小以最大程度地减少资源消耗

[点击展开]
  • 增加批大小会产生两种类型的资源成本:
    1. 前期成本,例如购买新硬件或重写训练管道以实现多 GPU / 多 TPU 训练。
    2. 使用成本,例如根据团队的资源预算计费、云提供商的计费、电费/维护成本。
  • 如果增加批大小会产生大量前期成本,则最好推迟增加批大小,直到项目成熟,并且更容易评估成本效益权衡。实施多主机并行训练计划可能会引入错误微妙的问题,因此最好从更简单的管道开始。(另一方面,当需要大量调优实验时,在过程的早期,训练时间的大幅加速可能非常有益)。
  • 我们将总使用成本(可能包括多种不同类型的成本)称为“资源消耗”。我们可以将资源消耗分解为以下组件:

资源消耗 =(每步的资源消耗)x(总步数)

  • 增加批量大小通常可以让我们减少总步骤数。资源消耗是增加还是减少将取决于每步消耗量如何变化。
    • 增加批大小可能会减少资源消耗。例如,如果批大小较大的每个步骤都可以在与批大小较小的相同硬件上运行(每个步骤的时间仅略有增加),则每个步骤的资源消耗的任何增加都可能被步骤数的减少所抵消。
    • 增加批大小可能不会更改资源消耗。例如,如果将批大小加倍使所需步骤数减半,并将使用的 GPU 数增加一倍,则总消耗量(以 GPU 小时为单位)将不会改变。
    • 增加批大小可能会增加资源消耗。例如,如果增加批大小需要升级硬件,则每步消耗的增加可能超过步骤数的减少。

更改批大小需要重新调整大多数超参数

[点击展开]
  • 大多数超参数的最佳值对批大小很敏感。因此,更改批大小通常需要重新开始优化过程。
  • 与批大小交互最强烈的超参数是优化器超参数(例如学习率、动量)和正则化超参数,因此对于每个批大小分别进行调优最为重要。
  • 在项目开始时选择批大小时,请记住这一点。如果以后需要切换到不同的批大小,则针对新的批大小重新调整所有内容可能很困难、耗时且成本高昂。

批次规范如何与批次大小交互

[点击展开]
  • 批次范数很复杂,通常应使用与梯度计算不同的批次大小来计算统计信息。有关详细讨论,请参阅批次规范部分

选择初始配置

  • 在开始超参数调优之前,我们必须确定起点。这包括指定 (1) 模型配置(例如层数),(2) 优化器超参数(例如学习率)和 (3) 训练步骤数。
  • 确定此初始配置将需要一些手动配置的训练运行和试错。
  • 我们的指导原则是找到一种简单、相对快速、相对低资源消耗的配置,以获得“合理”的结果。
    • “简单”意味着尽可能避免花里胡哨;这些始终可以在以后添加。即使花里胡哨的东西在未来被证明是有帮助的,在初始配置中添加它们也可能会浪费时间调整无用的功能和/或烘烤不必要的复杂性。
      • 例如,在添加花哨的衰减计划之前,从恒定的学习率开始。
    • 选择快速且消耗最少资源的初始配置将使超参数优化更加高效。
      • 例如,从较小的模型开始。
    • “合理”的性能取决于问题,但至少意味着经过训练的模型在验证集上的性能比随机机会好得多(尽管它可能足够糟糕,不值得部署)。
  • 选择训练步骤的数量涉及平衡以下张力:
    • 一方面,训练更多步骤可以提高性能并使超参数调优更容易(参见 Shallue 等人,2018 年)。
    • 另一方面,训练更少的步骤意味着每次训练运行更快,使用的资源更少,通过减少周期之间的时间并允许并行运行更多实验来提高调优效率。此外,如果最初选择了不必要的大步骤预算,则可能很难在以后进行更改,例如,一旦针对该步骤数调整了学习率计划。

提高模型性能的科学方法

就本文档而言,机器学习开发的最终目标是最大化已部署模型的效用。尽管开发过程的许多方面因应用程序而异(例如时间长度、可用计算资源、模型类型),但我们通常可以在任何问题上使用相同的基本步骤和原则。

我们下面的指导做出以下假设:

  • 已经有一个完全运行的训练管道以及获得合理结果的配置。
  • 有足够的计算资源可用于执行有意义的调优实验并并行运行至少多个训练作业。

增量调优策略

摘要:从简单的配置开始,逐步进行改进,同时建立对问题的洞察力。确保任何改进都基于强有力的证据,以避免增加不必要的复杂性。

  • 我们的最终目标是找到一种能够最大限度地提高模型性能的配置。
    • 在某些情况下,我们的目标是在固定的截止日期(例如提交比赛)之前最大限度地改进模型。
    • 在其他情况下,我们希望无限期地改进模型(例如,不断改进生产中使用的模型)。
  • 原则上,我们可以通过使用算法自动搜索可能配置的整个空间来最大化性能,但这不是一个实用的选择。
    • 可能的配置空间非常大,目前还没有足够复杂的算法在没有人类指导的情况下有效地搜索这个空间。
  • 大多数自动搜索算法依赖于手工设计的搜索空间,该空间定义了要搜索的配置集,而这些搜索空间可能非常重要。
  • 最大化性能的最有效方法是从简单的配置开始,逐步添加功能并进行改进,同时建立对问题的洞察力。
    • 我们在每一轮调整中使用自动搜索算法,并随着我们理解的增长不断更新我们的搜索空间。
  • 随着我们的探索,我们自然会发现越来越好的配置,因此我们的“最佳”模型将不断改进。
    • 当我们更新最佳配置(可能对应于也可能不对应于生产模型的实际发布)时,我们称之为启动
    • 对于每次发布,我们必须确保更改基于强有力的证据 - 而不仅仅是基于幸运配置的随机机会 - 这样我们就不会给训练管道增加不必要的复杂性。

在高级别上,我们的增量调优策略涉及重复以下四个步骤:

  1. 为下一轮实验确定一个适当范围的目标。
  2. 设计并运行一组试验,以朝着此目标取得进展。
  3. 了解我们能从结果中得到什么。
  4. 考虑是否启动新的最佳配置。

本节的其余部分将更详细地讨论此策略。

勘探与开发

概括: 大多数时候,我们的主要目标是深入了解问题。

  • 尽管人们可能认为我们会花费大部分时间想最大化验证集的性能,但实际上,我们花费大部分时间想深入了解问题,而相对较少的时间贪婪地关注验证错误。
    • 换句话说,我们把大部分时间花在“探索”上,只有一小部分时间花在“开发”上。
  • 从长远来看,如果我们想最大限度地提高最终性能,了解问题至关重要。将洞察力置于短期收益之上可以帮助我们:
    • 避免仅仅通过历史事故启动不必要的更改,这些更改恰好存在于性能良好的运行中。
    • 确定验证误差对哪些超参数最敏感,哪些超参数相互作用最多,因此需要一起重新调整,以及哪些超参数对其他变化相对不敏感,因此可以在未来的实验中修复。
    • 建议尝试潜在的新功能,例如,如果过度拟合是一个问题,则使用新的正则器。
    • 确定无济于事的特征,因此可以删除,从而降低未来实验的复杂性。
    • 识别超参数优化的改进何时可能饱和。
    • 围绕最优值缩小搜索空间,提高调优效率。
  • 当我们最终准备好贪婪时,我们可以纯粹关注验证错误,即使实验不能最大限度地了解调优问题的结构。

选择下一轮实验的目标

总结:每一轮实验都应该有一个明确的目标,并且范围足够窄,以便实验实际上可以朝着目标取得进展。

  • 每一轮实验都应该有一个明确的目标,并且范围足够窄,以便实验实际上可以朝着目标取得进展:如果我们尝试添加多个特征或一次回答多个问题,我们可能无法解开对结果的单独影响。
  • 示例目标包括:
    • 尝试对管道进行潜在的改进(例如,新的正则化器、预处理选择等)。
    • 了解特定模型超参数(例如激活函数)的影响
    • 贪婪地最小化验证错误。

设计下一轮实验

摘要:确定哪些超参数是科学的、令人讨厌的和固定的超参数,用于实验目标。创建一系列研究以比较科学超参数的不同值,同时优化令人讨厌的超参数。选择令人讨厌的超参数的搜索空间,以平衡资源成本和科学价值。

识别科学、有害和固定的超参数

[点击展开]
  • 对于给定的目标,所有超参数都将是科学超参数、有害超参数或固定超参数
    • 科学超参数是那些对我们想测量的模型性能的影响。
    • 令人讨厌的超参数是那些需要优化的超参数,以便公平地比较科学超参数的不同值。这类似于滋扰参数的统计概念。
    • 固定的超参数将在当前轮实验中固定其值。这些是超参数,在比较科学超参数的不同值时,其值不需要(或我们不希望它们)更改。
      • 通过为一组实验固定某些超参数,我们必须接受从实验中得出的结论可能对固定超参数的其他设置无效。换句话说,固定的超参数为我们从实验中得出的任何结论创造了警告。
  • 例如,如果我们的目标是“确定具有更多隐藏层的模型是否会减少验证误差”,那么隐藏层的数量就是一个科学超参数。
    • 学习率是一个令人讨厌的超参数,因为只有当学习率针对每个层数单独调整时,我们才能公平地比较具有不同隐藏层数的模型(最佳学习率通常取决于模型架构)。
    • 如果我们在之前的实验中确定激活函数的最佳选择对模型深度不敏感,或者如果我们愿意将关于隐藏层数的结论限制为仅涵盖激活函数的特定选择,则激活函数可能是一个固定的超参数。或者,如果我们准备为每个数量的隐藏层单独调整它,它可能是一个令人讨厌的参数。
  • 特定超参数是科学超参数、有害超参数还是固定超参数不是该超参数固有的,而是根据实验目标而变化的。
    • 例如,激活函数的选择可以是科学超参数(ReLU 或 tanh 是我们问题的更好选择吗?),一个令人讨厌的超参数(当我们允许几种不同的可能激活函数时,最好的 5 层模型是否比最好的 6 层模型更好?),或者一个固定的超参数(对于 ReLU 网络,在特定位置添加批量归一化是否有帮助?)。
  • 在设计新一轮实验时,我们首先确定实验目标的科学超参数。
    • 在这个阶段,我们认为所有其他超参数都是令人讨厌的超参数。
  • 接下来,我们将一些令人讨厌的超参数转换为固定的超参数。
    • 有了无限的资源,我们会将所有非科学超参数保留为令人讨厌的超参数,这样我们从实验中得出的结论就不会受到关于固定超参数值的警告。
    • 然而,我们想调整的令人讨厌的超参数越多,我们未能针对科学超参数的每个设置充分调整它们并最终从我们的实验中得出错误结论的风险就越大。
      • 如下所述,我们可以通过增加计算预算来应对这种风险,但通常我们的最大资源预算低于调整所有非科学超参数所需的预算。
    • 我们选择将一个令人讨厌的超参数转换为一个固定的超参数,当我们判断,修复它所引入的警告比将其作为令人讨厌的超参数包含的成本要轻。
      • 给定的有害超参数与科学超参数交互的次数越多,修复其值的破坏性就越大。例如,权重衰减强度的最佳值通常取决于模型大小,因此假设权重衰减的单个特定值,比较不同的模型大小将不是很有见地。
  • 尽管我们分配给每个超参数的类型取决于实验目标,但对于某些类别的超参数,我们有以下经验法则:
    • 在各种优化器超参数(例如学习率、动量、学习率计划参数、Adam beta 等)中,至少有一些是令人讨厌的超参数,因为它们往往与其他变化交互最多。
      • 它们很少是科学的超参数,因为像“当前管道的最佳学习率是多少?”这样的目标并没有提供太多的见解——无论如何,最佳设置很容易随着下一次管道更改而改变。
      • 尽管由于资源限制,或者当我们有特别有力的证据表明它们不与科学参数交互时,我们可能会偶尔修复其中一些,但我们通常应该假设优化器超参数必须单独调整,以便在科学超参数的不同设置之间进行公平比较,因此不应该修复。
        • 此外,我们没有先验的理由偏爱一个优化器超参数值而不是另一个(例如,它们通常不会以任何方式影响正向传递或梯度的计算成本)。
    • 相比之下,优化器的选择通常是科学超参数或固定超参数。
      • 如果我们的实验目标涉及在两个或多个不同的优化器之间进行公平的比较(例如,“确定哪个优化器在给定的步骤数中产生最低的验证误差”),则这是一个科学超参数。
      • 或者,出于各种原因,我们可能会使其成为固定超参数,包括(1)先前的实验使我们相信,对于我们的问题的最佳优化器对当前的科学超参数不敏感;和/或 (2) 我们更喜欢使用此优化器比较科学超参数的值,因为它的训练曲线更容易推理;和/或 (3) 我们更喜欢使用此优化器,因为它比替代方案使用更少的内存。
    • 正则化技术引入的超参数通常是令人讨厌的超参数,但我们是否包括正则化技术是一个科学的或固定的超参数。
      • 例如,dropout 增加了代码的复杂性,因此在决定是否包含它时,我们会将“no dropout”与“dropout”作为科学超参数,并将 dropout 率设为令人讨厌的超参数。
        • 如果我们决定根据这个实验将 dropout 添加到我们的管道中,那么 dropout 率在未来的实验中将是一个令人讨厌的超参数。
    • 体系结构超参数通常是科学或固定的超参数,因为体系结构更改可能会影响服务和训练成本、延迟和内存要求。
      • 例如,层数通常是一个科学或固定的超参数,因为它往往会对训练速度和内存使用产生巨大影响。
  • 在某些情况下,令人讨厌和固定超参数的集合将取决于科学超参数的值。
    • 例如,假设我们想确定哪个优化器从 Nesterov 动量和 Adam 中产生最小的验证误差。科学超参数是 ,它取值。该值引入了有害/固定超参数,但该值引入了有害/固定超参数。
      optimizer
      {"Nesterov_momentum", "Adam"}
      optimizer="Nesterov_momentum"
      {learning_rate, momentum}
      optimizer="Adam"
      {learning_rate, beta1, beta2, epsilon}
    • 仅存在于科学超参数的某些值的超参数称为条件超参数
    • 我们不应该仅仅因为它们具有相同的名称就假设两个条件超参数是相同的!在上面的示例中,调用的条件超参数是 与 的不同超参数。它在两种算法中的作用相似(尽管不相同),但在每个优化器中运行良好的值范围通常相差几个数量级。
      learning_rate
      optimizer="Nesterov_momentum"
      optimizer="Adam"

创建一组算例

[点击展开]
  • 一旦我们确定了科学和令人讨厌的超参数,我们就会设计一个“研究”或一系列研究,以朝着实验目标取得进展。
    • 算例指定了一组要运行的超参数配置以进行后续分析。每个配置称为“试用”。
    • 创建研究通常涉及选择因试验而异的超参数,选择这些超参数可以取的值(“搜索空间”),选择试验数量,以及选择自动搜索算法以从搜索空间中抽取许多试验。或者,我们可以通过手动指定超参数配置集来创建研究。
  • 研究的目的是使用不同值的科学超参数运行管道,同时“优化”(或“优化”)令人讨厌的超参数,以便科学超参数的不同值之间的比较尽可能公平。
  • 在最简单的情况下,我们会对科学参数的每种配置进行单独的研究,其中每个研究都会调整令人讨厌的超参数。
    • 例如,如果我们的目标是从 Nesterov 动量和 Adam 中选择最佳优化器,我们可以创建一个研究,其中 和 讨厌的超参数是 ,另一个研究 其中 和 讨厌的超参数是 。我们将通过从每项研究中选择表现最佳的试验来比较两个优化器。
      optimizer="Nesterov_momentum"
      {learning_rate, momentum}
      optimizer="Adam"
      {learning_rate, beta1, beta2, epsilon}
    • 我们可以使用任何无梯度优化算法,包括贝叶斯优化或进化算法等方法来优化令人讨厌的超参数,尽管我们更喜欢在调优的探索阶段使用准随机搜索,因为它在此设置中具有多种优势。探索结束后,如果有最先进的贝叶斯优化软件,那就是我们的首选。
  • 在更复杂的情况下,我们想要比较大量科学超参数的值,并且进行那么多独立研究是不切实际的,我们可以将科学参数包含在与滋扰超参数相同的搜索空间中,并使用搜索算法在单个研究中科学和滋扰超参数的值进行采样。
    • 采用这种方法时,条件超参数可能会导致问题,因为很难指定搜索空间,除非科学超参数的所有值的有害超参数集都相同。
    • 在这种情况下,我们更喜欢使用准随机搜索而不是更高级的黑盒优化工具,因为它确保我们获得相对均匀的科学超参数值采样。无论搜索算法如何,我们都需要以某种方式确保它统一搜索科学参数。

在信息丰富和负担得起的实验之间取得平衡

[点击展开]
  • 在设计一项研究或一系列研究时,我们需要分配有限的预算,以充分实现以下三个目标:
    1. 比较足够多的不同科学超参数值。
    2. 在足够大的搜索空间上调整令人讨厌的超参数。
    3. 对令人讨厌的超参数的搜索空间进行足够密集的采样。
  • 我们越能实现这三个目标,我们就越能从实验中提取出更多的见解。
    • 比较尽可能多的科学超参数值可以扩大我们从实验中获得的见解的范围。
    • 包括尽可能多的滋扰超参数,并允许每个滋扰超参数在尽可能宽的范围内变化,这增加了我们的信心,即对于科学超参数的每个配置,搜索空间中都存在令人讨厌的超参数的“良好”值。
      • 否则,我们可能会在科学超参数的值之间进行不公平的比较,因为我们不搜索令人讨厌的参数空间的可能区域,其中科学参数的某些值可能具有更好的值。
    • 尽可能密集地对干扰超参数的搜索空间进行采样可以增加我们的信心,即搜索过程将找到恰好存在于搜索空间中的任何良好设置。
      • 否则,我们可能会在科学参数的值之间进行不公平的比较,因为某些值在对令人讨厌的超参数进行采样时会变得更幸运。
  • 不幸的是,这三个方面的任何改进都需要增加试验的数量,从而增加资源成本,或者找到在其他方面节省资源的方法。
    • 每个问题都有自己的特性和计算约束,因此如何在这三个方面分配资源需要一定程度的领域知识。
    • 在进行研究后,我们总是想了解研究是否足够好地调整了令人讨厌的超参数(即搜索足够大的空间足够广泛)以公平地比较科学超参数(如下所述)。

从实验结果中提取见解

摘要:除了尝试实现每组实验的原始科学目标外,还要检查其他问题的清单,如果发现问题,请修改实验并重新运行它们。

  • 最终,每组实验都有一个特定的目标,我们希望评估实验为该目标提供的证据。
    • 然而,如果我们提出正确的问题,我们经常会发现在一组给定的实验朝着其原始目标取得很大进展之前需要纠正的问题。
      • 如果我们不问这些问题,我们可能会得出错误的结论。
    • 由于运行实验可能很昂贵,我们还希望借此机会从每组实验中提取其他有用的见解,即使这些见解与当前目标没有直接相关。
  • 在分析一组给定的实验以朝着其原始目标取得进展之前,我们应该问自己以下其他问题:
    • 搜索空间是否足够大?
      • 如果研究中的最佳点在一个或多个维度上接近搜索空间的边界,则搜索可能不够宽。在这种情况下,我们应该进行另一项具有扩展搜索空间的研究。
    • 我们是否从搜索空间中抽取了足够的点?
      • 如果没有,请运行更多点或在调整目标中不那么雄心勃勃。
    • 每项研究中有多少试验是不可行的(即试验存在分歧,损失值非常差,或者因为它们违反了某些隐含约束而根本无法运行)?
      • 当研究中很大一部分点不可行时,我们应该尝试调整搜索空间以避免对这些点进行采样,这有时需要重新参数化搜索空间。
      • 在某些情况下,大量不可行的点可能表明训练代码中存在错误。
    • 模型是否出现优化问题?
    • 我们可以从最佳试验的训练曲线中学到什么?
      • 例如,最佳试验的训练曲线是否与有问题的过拟合一致?
  • 如有必要,根据上述问题的答案,完善最近的研究(或研究组),以改善检索空间和/或抽样更多的试验,或采取其他一些纠正措施。
  • 一旦我们回答了上述问题,我们就可以继续评估实验为我们最初目标提供的证据(例如,评估更改是否有用)。

识别错误的搜索空间边界

[点击展开]
  • 如果从搜索空间中采样的最佳点接近其边界,则搜索空间是可疑的。如果我们在这个方向上扩大搜索范围,我们可能会找到更好的点。
  • 为了检查搜索空间边界,我们喜欢在我们所谓的基本超参数轴图上绘制已完成的试验,其中我们绘制验证目标值与其中一个超参数(例如学习率)。图上的每个点对应于一个试验。
    • 每个试验的验证目标值通常应该是它在培训过程中达到的最佳值。

错误的搜索空间边界示例 良好的搜索空间边界示例

图1:错误的搜索空间边界和可接受的搜索空间边界的示例。

  • 图 1 中的曲线显示了错误率(越低越好)与初始学习率的关系。
  • 如果最佳点聚集在搜索空间的边缘(在某个维度上),则可能需要扩展搜索空间边界,直到最佳观测点不再靠近边界。
  • 通常,一项研究将包括“不可行的”试验,这些试验会发散或得到非常糟糕的结果(在上面的图中用红色X标记)。

未在搜索空间中采样足够的点

[点击展开]
  • 通常,很难知道搜索空间是否已足够密集地采样。🤖
  • 进行更多的试验当然更好,但代价显而易见。
  • 由于很难知道何时采样足够多,因此我们通常会对我们可以承受的采样进行采样,并尝试通过反复查看各种超参数轴图并想了解搜索空间的“良好”区域中有多少点来校准我们的直觉置信度。

检查训练曲线

[点击展开]

摘要:检查训练曲线是识别常见故障模式的简单方法,可以帮助我们确定下一步要采取的操作的优先级。

  • 虽然在许多情况下,我们实验的主要目标只需要考虑每个试验的验证误差,但在将每个试验减少到一个数字时,我们必须小心,因为它可以隐藏有关表面之下发生的事情的重要细节。
  • 对于每项研究,我们总是查看至少最好的几个试验的训练曲线(绘制的训练误差和验证误差与训练期间的训练步骤)。
  • 即使这对于解决主要实验目标不是必需的,检查训练曲线也是识别常见故障模式的简单方法,可以帮助我们确定下一步要采取的操作的优先级。
  • 在检查训练曲线时,我们对以下问题感兴趣。
  • 是否有任何试验表现出有问题的过度拟合?
    • 当验证错误在训练期间的某个时间点开始增加时,就会发生有问题的过度拟合。
    • 在实验环境中,我们通过为科学超参数的每个设置选择“最佳”试验来优化令人讨厌的超参数,我们应该至少检查每个最佳试验中是否存在有问题的过度拟合对应于我们正在比较的科学超参数的设置。
      • 如果任何最好的试验表现出有问题的过拟合,我们通常希望在比较科学超参数的值之前,使用其他正则化技术和/或更好地调整现有的正则化参数。
        • 如果科学超参数包含正则化参数,这可能不适用,因为如果这些正则化参数的低强度设置导致有问题的过拟合,也就不足为奇了。
      • 使用常见的正则化技术来减少过度拟合通常很简单,这些技术会增加最小的代码复杂性或额外的计算(例如dropout,标签平滑,权重衰减),因此将其中一个或多个添加到下一轮实验中通常没什么大不了的。
      • 例如,如果科学超参数是“隐藏层数”,而使用最多隐藏层数的最佳试验表现出有问题的过拟合,那么我们通常更愿意使用额外的正则化再次尝试,而不是立即选择较少数量的隐藏层。
      • 即使没有一个“最佳”试验表现出有问题的过拟合,如果它发生在任何试验中,仍然可能存在问题。
        • 选择最佳试验可抑制表现出有问题的过拟合的配置,而有利于那些没有问题的过拟合的配置。换句话说,它将有利于具有更多正则化的配置。
        • 但是,任何使训练变得更糟的东西都可以充当正则器,即使它不是这样打算的。例如,选择较小的学习率可以通过阻碍优化过程来规范训练,但我们通常不希望以这种方式选择学习率。
        • 因此,我们必须意识到,对于科学超参数的每个设置,可能会以有利于某些科学或令人讨厌的超参数的“坏”值的方式选择。
  • 训练中是否存在很高的步进方差或训练后期的验证误差?
    • 如果是这样,这可能会干扰我们比较不同科学超参数值的能力(因为每个试验都随机以“幸运”或“不幸”步骤结束)以及我们在生产中重现最佳试验结果的能力(因为生产模型可能不会以与研究中相同的“幸运”步骤结束)。
    • 分步方差的最可能原因是批次方差(从每个批次的训练集中随机抽样样本)、小验证集以及在训练后期使用过高的学习率。
    • 可能的补救措施包括增加批量大小、获取更多验证数据、使用学习率衰减或使用 Polyak 平均。
  • 训练结束时试验是否仍在改善?
  • 训练集和验证集的性能是否在最后的训练步骤之前很久就饱和了?
  • 虽然我们不能一一列举,但通过检查训练曲线,还有许多其他行为可以变得明显(例如,训练期间训练损失增加通常表明训练管道中存在错误)。

检测更改对隔离图是否有用

[点击展开]

隔离图,用于研究在 ImageNet 上训练的 ResNet-50 的最佳权重衰减值。

图2:隔离图,用于研究在 ImageNet 上训练的 ResNet-50 的最佳权重衰减值。

  • 通常,一组实验的目标是比较科学超参数的不同值。
    • 例如,我们可能想要确定导致最佳验证误差的权重衰减值。
  • 隔离图是基本超参数轴图的特例。隔离图上的每个点对应于跨部分(或全部)有害超参数的最佳试验的性能
    • 换句话说,我们在“优化”了令人讨厌的超参数之后绘制模型性能。
  • 隔离图可以更轻松地在科学超参数的不同值之间进行同类比较。
  • 例如,图 2 揭示了权重衰减的值,该值可为在 ImageNet 上训练的 ResNet-50 的特定配置产生最佳验证性能。
    • 如果我们的目标是确定是否包括权重衰减,那么我们将比较该图中的最佳点与无权重衰减的基线。为了进行公平比较,基线也应该同样调整其学习率。
  • 当我们有由(准)随机搜索生成的数据并考虑隔离图的连续超参数时,我们可以通过对基本超参数轴图的 x 轴值进行分桶并在存储桶定义的每个垂直切片中进行最佳试验来近似隔离图。

自动执行一般有用的绘图

[点击展开]
  • 生成地块的努力越多,我们就越不可能尽可能多地查看它们,因此我们应该设置我们的基础设施以自动生成尽可能多的地块。
  • 至少,我们为实验中变化的所有超参数自动生成基本的超参数轴图。
  • 此外,我们自动生成所有试验的训练曲线,并尽可能轻松地找到每个研究中最好的几个试验并检查它们的训练曲线。
  • 我们可以添加许多其他有用的潜在绘图和可视化效果。虽然上面描述的是一个很好的起点,但套用杰弗里·辛顿的话来说,“每次你策划新的东西,你都会学到新的东西。

确定是采用训练管道更改还是超参数配置

摘要:在决定是否更改我们的模型或训练过程或采用新的超参数配置时,我们需要了解结果中的不同变异来源。

  • 当我们尝试改进模型时,我们可能会观察到,与现有配置相比,特定的候选更改最初实现了更好的验证误差,但发现在重复实验后没有一致的优势。非正式地,我们可以将可能导致这种不一致结果的最重要变异源分为以下几大类:
    • 训练过程方差、训练方差或试验方差:我们在使用相同超参数但不同随机种子的训练运行之间看到的变化。
      • 例如,不同的随机初始化、训练数据随机、辍学掩码、数据增强操作模式和并行算术运算排序都是试验方差的潜在来源。
    • 超参数搜索方差或研究方差:由我们选择超参数的过程引起的结果变化。
      • 例如,我们可能会对特定的搜索空间运行相同的实验,但使用两个不同的种子进行准随机搜索,并最终选择不同的超参数值。
    • 数据收集和采样方差:从任何类型的随机拆分为训练、验证和测试数据的方差,或由于训练数据生成过程引起的方差
  • 使用苛刻的统计检验对有限验证集上估计的验证错误率进行比较是很好的,但通常仅试验方差就可以在使用相同超参数设置的两个不同训练模型之间产生统计上的显着差异。
  • 当想得出超出超参数空间中单个点水平的结论时,我们最关心的是研究方差。
    • 研究方差取决于试验数量和检索空间,我们已经看到它大于试验方差的情况以及它小得多的情况。
  • 因此,在采用候选更改之前,请考虑运行最佳试验 N 次来表征运行间试验方差。
    • 通常,我们只能在对管道进行重大更改后重新表征试验方差,但在某些应用中,我们可能需要更新鲜的估计。
    • 在其他应用中,表征试验方差的成本太高,不值得。
  • 归根结底,尽管我们只想采用能够产生真正改进的更改(包括新的超参数配置),但要求完全确定某些帮助也不是正确的答案。
  • 因此,如果一个新的超参数点(或其他变化)得到比基线更好的结果(尽可能考虑新点和基线的重新训练方差),那么我们可能应该采用它作为未来比较的新基线。
    • 但是,我们只应该采用能够产生超过它们增加的任何复杂性的改进的更改。

探索结束后

总结:贝叶斯优化工具是一个引人注目的选择,一旦我们完成了对良好搜索空间的探索,并决定应该调整哪些超参数。

  • 在某些时候,我们的优先事项将从了解有关调优问题的更多信息转移到生成要启动或以其他方式使用的单个最佳配置。
  • 在这一点上,应该有一个精细的搜索空间,舒适地包含最佳观察试验周围的局部区域,并且已经充分采样。
  • 我们的探索工作应该揭示了要调优的最重要的超参数(以及它们的合理范围),我们可以用来构建一个搜索空间,使用尽可能大的调优预算为最终的自动调优研究构建搜索空间。
  • 由于我们不再关心最大化我们对调优问题的洞察力,因此准随机搜索的许多优点不再适用,应该使用贝叶斯优化工具来自动找到最佳的超参数配置。
    • 开源 Vizier 实现了各种用于调整 ML 模型的复杂算法,包括贝叶斯优化算法。
    • 如果搜索空间包含大量发散点(获得 NaN 训练损失甚至训练损失比平均值差许多标准差的点),则使用黑盒优化工具正确处理发散试验非常重要(请参阅未知约束的贝叶斯优化,了解处理此问题的绝佳方法)。开源 Vizier 通过将试验标记为不可行来支持不同的点,尽管它可能不使用我们首选的 Gelbart 等人的方法,具体取决于它的配置方式。
  • 此时,我们还应考虑检查测试集的性能。
    • 原则上,我们甚至可以将验证集折叠到训练集中,并重新训练贝叶斯优化找到的最佳配置。但是,这仅在将来不会使用此特定工作负载启动时才适用(例如一次性 Kaggle 竞赛)。

确定每个训练运行的步数

  • 有两种类型的工作负载:受计算限制的工作负载和不受计算限制的工作负载。
  • 当训练是计算绑定的时,训练受限于我们愿意等待的时间,而不是我们拥有多少训练数据或其他因素。
    • 在这种情况下,如果我们能以某种方式训练更长时间或更有效率,我们应该看到更低的训练损失,并且通过适当的调整,验证损失得到改善。
    • 换句话说,加快训练就等于提高训练,“最优”训练时间总是“只要我们能承受”。
    • 也就是说,仅仅因为工作负载受计算限制并不意味着训练时间更长/更快是改善结果的唯一方法。
  • 当训练不受计算约束时,我们可以随心所欲地训练,而且在某些时候,长时间的训练没有多大帮助(甚至会导致有问题的过度拟合)。
    • 在这种情况下,我们应该期望能够训练到非常低的训练损失,以至于训练时间更长可能会略微减少训练损失,但不会有意义地减少验证损失。
    • 特别是当训练不受计算限制时,更慷慨的训练时间预算可以使调优更容易,尤其是在调优学习率衰减计划时,因为它们与训练预算有特别强的交互作用。
      • 换句话说,非常吝啬的训练时间预算可能需要一个调整到完美的学习率衰减计划,以实现良好的错误率。
  • 无论给定工作负载是否受计算限制,增加梯度方差(跨批次)的方法通常会导致训练进度变慢,因此可能会增加达到特定验证损失所需的训练步骤数。高梯度方差可能由以下原因引起:
    • 使用较小的批量大小
    • 添加数据增强
    • 添加某些类型的正则化(例如 dropout)

确定训练不受计算限制时的训练时间

  • 我们的主要目标是确保我们训练的时间足够长,以使模型达到最佳结果,同时避免在训练步骤的数量上过度浪费。
  • 如有疑问,请延长训练时间。假设正确使用了回顾性(最佳)检查点选择并且检查点足够频繁,则训练时间较长时,性能永远不会下降。
  • 永远不要调整研究中的数字。选择一个值并将其用于所有试用。从这些试验中,绘制回顾性检查点选择找到的训练步骤,以便优化 的选择。
    max_train_steps
    max_train_steps
    • 例如,如果最佳步骤始终是在训练的前 10% 期间,则最大步数太高了。
    • 或者,如果最佳步骤始终是在最后 25% 的训练中,我们可能会从更长的训练时间和重新调整衰减计划中受益。
  • 当架构或数据发生变化(例如,添加数据增强)时,理想的训练步骤数可能会发生变化。
  • 下面我们描述了如何根据使用恒定学习率“完全拟合”训练集所需的步骤数来选择初始候选值。
    max_train_steps
    • 请注意,我们没有以精确或数学上明确定义的方式使用短语“完全拟合训练集”。它只是作为一个非正式的描述符,以表明非常低的培训损失。
      • 例如,当使用对数损失进行训练时,如果没有正则化项,我们可能会看到训练损失不断缓慢改善,直到达到浮点限制,因为网络权重无限制地增长,并且训练集上的模型预测变得越来越自信。在这种情况下,我们可以说模型在训练集上的误分类误差达到零时“完全拟合”训练集。
    • 如果训练过程中的梯度噪声量增加,我们发现的起始值可能需要增加。
      max_train_steps
      • 例如,如果将数据增强或正则化器(如 dropout)引入模型。
    • 如果训练过程以某种方式改善,则可能会减少。
      max_train_steps
      • 例如,使用更好的优化器或更好的调整学习率计划。

使用学习率扫描为max_train_steps选择初始候选项的算法

[点击展开]
  • 此过程假设不仅可以“完美”拟合训练集,而且可以使用恒定的学习率计划来实现。
  • 如果可以完美拟合整个训练集,那么必须存在一个完全拟合训练集的配置(具有某个值);找到任何此类配置并将其值用作起点。
    max_train_steps
    max_train_steps
    N
  • 运行恒定学习率扫描(即网格搜索学习率),无需数据增强,也没有正则化,其中每个试验都训练步骤。
    N
  • 在扫描中以最快的速度试验以达到完美的训练性能所需的步数是我们最初的猜测。
    max_train_steps
  • 注意:糟糕的搜索空间可能会使自我欺骗成为可能。
    • 例如,如果研究中的所有学习率都太小,我们可能会错误地得出结论,认为需要非常大的值。
      max_train_steps
    • 至少,我们应该检查研究中的最佳学习率是否不在搜索空间的边界。

确定训练受计算限制时训练多长时间

  • 在某些情况下,训练损失会无限期地改善,我们的耐心和计算资源成为限制因素。
  • 如果训练损失(甚至验证损失)无限期地持续改善,我们是否应该始终在负担得起的时间内进行训练?不一定。
    • 我们也许能够通过运行大量较短的实验并为我们希望推出的模型保留最长的“生产长度”运行来更有效地进行调整。
    • 随着试验的训练时间接近我们的耐心极限,调整实验对于我们潜在的发射候选者变得更加相关,但我们可以完成的实验更少。
    • 在只训练~10%的生产长度时,我们可能有很多问题可以回答,但始终存在一个风险,即我们在这个时间限制下的结论不适用于生产长度的20%的实验,更不用说100%。
  • 通过增加每次试验的训练步骤限制来调整多轮是一种明智的方法。
    • 我们可以做任意多轮,但通常 1-3 轮是最实用的。
    • 从本质上讲,尝试使用周转时间非常快的试验来尽可能多地了解问题,权衡调整的彻底性与最终最长运行的相关性。
    • 一旦给定的每次试验时间限制产生了有用的见解,我们就可以增加训练时间并继续调整,根据需要从较短的运行中仔细检查我们的结论。
  • 作为起点,我们建议进行两轮调整:
    • 第 1 轮:缩短运行时间以找到好的模型和优化器超参数。
    • 第 2 轮:很少在良好的超参数点上进行长时间运行以获得最终模型。
  • →最大的问题是如何调整学习率衰减时间表。
    Round i
    Round i+1
    • 在两轮之间调整学习率计划时,一个常见的陷阱是使用所有额外的训练步骤,而学习率太小。

第 1

[点击展开]
  • 不幸的是,当训练长度显着增加时,不能保证在简短、不完整的训练中发现的良好超参数仍然是不错的选择。但是,对于某些类型的超参数,它们通常具有足够的相关性,以使第 1 轮有用。
  • 我们希望在较短的运行中发现哪些超参数值会转移到较长的训练运行中?对于所有这些,我们需要更多的研究。但根据我们目前所知道的情况,以下是作者的怀疑,按转移概率降低的顺序排列:
    • 很有可能转移
      • 早期训练不稳定可以在第一轮调优中使用较少数量的训练步骤来解决。也许这些超参数是最接近我们拥有的确定转移赌注的东西。
        • 预热长度
        • 初始化
    • 可能会转移
      • 模型架构 - 模型架构中的戏剧性胜利通常会转移,但可能有很多反例。
    • 可能会转移
      • 优化算法/优化器超参数 - 我们认为这将“松散”转移。它肯定比上面的东西弱。
      • 数据增强
      • 正规化
        • 如果不可能完全拟合训练集,则模型可能处于正则化不太可能有很大帮助的状态下。
    • 不太可能转移
      • 学习率时间表:不太可能完美转移。
        • 这篇论文表明,即使是衰变时间表也会转移,但我们一般不相信这是真的。示例:在小 # 个训练步骤上调整 sqrt 衰减,然后扩展到大 # 将导致大多数训练发生在过小的步骤上。
          • 在极端训练预算的极限下,人们可能会对大多数时间表做得“足够好”,但如果对其进行调整,可能会看到明显的性能改进。
        • 了解随机元优化中的短视偏差描述了想短视地选择学习率的危险。

第 2

[点击展开]
  • 运行第 1 轮中的最佳超参数配置。
  • (推测)🤖使用额外的步骤以高学习率延长训练时间。
    • 例如,如果线性时间表,则从第 1 轮开始保持衰减的长度固定,并在开始时延长常数 lr 的周期。
    • 对于余弦衰减,只需保留第 1 轮的基础 lr 并像在 Chinchilla 纸中一样扩展。
      max_train_steps
  • 对于建模和调优管道非常成熟以及生产训练运行时间非常长且昂贵的团队来说,更多的轮次可能是有意义的,但它们往往是矫枉过正的。
    • 我们已经介绍了如何从步骤 1 转移到步骤 2→。如果我们不关心分析时间,并且是否有效利用计算是最重要的问题,那么理想的情况是在许多不同的调整轮次中成倍增加训练运行的长度(从而增加完成研究的端到端时间)。
      • 在每一轮中,我们都会系统地确保我们的选择继续保持下去。
      • 新想法通过一个管道,使用从步骤 i 到步骤 i+1 的运行时间越来越长的实验来逐步降低风险。

培训管道的其他指南

优化输入管道

摘要:输入绑定管道的原因和干预高度依赖于任务;使用探查器并注意常见问题。

  • 使用适当的探查器来诊断输入绑定管道。例如,Perfetto for JAX 或 TensorFlow profiler for TensorFlow。
  • 最终,具体原因和干预措施将高度依赖于任务。更广泛的工程考虑(例如,最小化磁盘占用空间)可能需要更差的输入管道性能。
  • 常见原因:
    • 数据未与训练过程共置,从而导致 I/O 延迟(通过网络读取训练数据时可能会发生这种情况)。
    • 昂贵的在线数据预处理(考虑在脱机后执行此操作并保存)。
    • 干扰数据管道预取的意外同步屏障。例如,在 CommonLoopUtils 中同步设备和主机之间的指标时(链接)。
  • 常见提示:
    • 用于预取示例的仪器输入管道(例如 tf.data.Dataset.prefetch)
    • 在管道中尽早从每个要素/元数据中删除未使用的功能/元数据。
    • 增加为输入管道生成示例的作业数的复制。例如,通过使用 tf.data 服务

评估模型性能

摘要:以比训练更大的批量大小运行评估。按固定的步骤间隔运行评估,而不是按固定的时间间隔运行。

评估设置

[点击展开]
  • 我们可以在几个设置中评估模型的性能。
    • 联机评估 - 当模型在生产环境中提供预测时,将收集指标。
    • 脱机评估 - 在代表生产环境的脱机训练/验证/测试集上运行模型时收集指标。
    • 定期评估 - 在模型训练期间收集指标,这些指标可能是脱机评估的代理和/或脱机评估中使用的数据子集。
  • 在线评估是黄金标准,但在模型开发阶段通常是不切实际的。
  • 根据问题的不同,离线评估可能相当复杂,计算成本也很高。
  • 定期评估是最实用、最经济的选择,但可能无法完全代表生产环境。
    • 在定期评估期间,我们的目标是使用离线评估的权宜之计,而不会牺牲我们在训练期间获得的信号的可靠性。

设置定期评估

[点击展开]
  • 我们在训练期间运行定期评估,以实时监控其进度,以促进回顾性模型检查点选择,以便我们可以在训练结束时检查训练曲线
  • 最简单的配置是在同一计算实例中执行训练和定期评估,定期在训练和评估之间交替。
    • 在这种情况下,用于执行评估的批大小应至少与用于训练的批大小一样大,因为在评估期间不需要维护模型激活,从而降低了每个示例的计算要求。
  • 定期评估应按固定的步骤间隔进行,而不是时间间隔。
    • 基于时间间隔进行评估可能会使解释训练曲线变得更加困难,尤其是当训练可能遭受训练作业抢占、网络延迟问题等影响时。
  • 有效/测试指标中的周期性(使用随机训练/验证/测试拆分时)可能指示实现错误,例如测试数据与训练数据重叠,或训练数据未正确洗牌。定期评估步骤间隔可以使这些问题更容易发现。
  • 当评估集不能被批大小整除时,可能会出现部分批次。确保填充的示例正确加权,以防止损失函数被它们偏置。通常,这些填充示例的权重可以为零。
  • 每次评估保存足够的信息以支持离线分析。理想情况下,我们会将预测保存在选定的单个示例上,因为它们对于调试非常宝贵。
    • 通过生成 SavedModel 等工件,可以轻松地在评估作业完成后执行临时模型检查。

选择样本进行定期评估

[点击展开]
  • 定期评估作业的运行速度可能不够快,无法在合理的时间内计算完整脱机评估集的指标。这通常需要对数据进行抽样以进行定期评估。
  • 在构建采样数据集时,我们会考虑以下因素:
    • 样本量
      • 检查在定期作业使用的采样数据集上计算的性能是否与整个离线评估集的性能匹配,即采样集和完整数据集之间没有偏差。
      • 用于定期评估的数据集应该足够小,以便于生成整个模型预测,但又足够大,可以准确衡量对模型的改进(即不会被标签噪声淹没)。
      • 它应该足够大,以便按顺序容纳跨试验的多个此类评估,并且仍然产生准确的估计值。也就是说,避免随着时间的推移自适应地“拟合”验证集,而不是推广到保留的测试集。然而,这种考虑很少是一个实际问题。
    • 不平衡的数据集
      • 对于不平衡的数据集,罕见类示例的性能通常会很嘈杂。
      • 对于类标签中样本数量较少的数据集,请记录正确预测的示例数,以更深入地了解准确性的提高(.05灵敏度的提高听起来令人兴奋,但这只是另一个正确的示例吗?

保存检查点并回顾性地选择最佳检查点

摘要:运行固定数量的步数的训练,并从运行中回顾性地选择最佳检查点。

  • 大多数深度学习框架都支持模型检查点。也就是说,模型的当前状态会定期保留在磁盘上。这使训练作业能够灵活应对计算实例中断。
  • 最佳检查点通常不是最后一个检查点,特别是当验证集性能不会随着时间的推移而继续增加而是围绕特定值波动时。
  • 设置管道以跟踪训练期间到目前为止看到的 N 个最佳检查点。在训练结束时,模型选择是选择训练期间看到的最佳检查点的问题。我们称之为回顾性最佳检查点选择
  • 通常不需要支持预期的提前停止,因为我们预先指定了试用预算,并保留了迄今为止看到的 N 个最佳检查点。

设置实验跟踪

概括: 在跟踪不同的实验时,请务必注意一些要点,例如研究中检查点的最佳表现以及对研究的简短描述。

  • 我们发现,在电子表格中跟踪实验结果对我们处理的各种建模问题很有帮助。它通常具有以下列:
    • 研究名称
    • 指向存储算例配置的位置的链接。
    • 研究的注释或简短描述。
    • 运行的试验数
    • 研究中最佳检查点的验证集的性能。
    • 具体的复制命令或关于启动培训所需的未提交更改的说明。
  • 找到一个跟踪系统,该系统至少可以捕获上面列出的信息,并且对执行此操作的人来说很方便。未跟踪的实验也可能不存在。

批量规范化实现详细信息

摘要:如今,批处理规范通常可以用 LayerNorm 替换,但在不能的情况下,在更改批量大小或主机数量时会出现棘手的细节。

  • 批次规范使用激活在当前批次上的均值和方差对激活进行规范化,但在多设备设置中,除非显式同步,否则每个设备上的这些统计信息都不同。
  • 轶事报告(主要在 ImageNet 上)说,仅使用 ~64 个示例计算这些归一化统计数据在实践中实际上效果更好(参见本文中的 Ghost Batch Norm)。
  • 分离总批次大小和用于计算批次规范统计量的示例数对于批次大小比较特别有用。
  • 幽灵批处理规范实现并不总是正确处理每个设备的批处理大小>虚拟批处理大小的情况。在这种情况下,我们实际上需要对每个设备上的批次进行子采样,以获得适当数量的批次规范统计示例。
  • 测试模式批次范数中使用的指数移动平均线只是训练统计数据的线性组合,因此这些 EMA 只需在将它们保存在检查点之前进行同步。但是,批处理规范的一些常见实现不会同步这些 EMA,而只会保存第一个设备的 EMA。

多主机管道的注意事项

总结:对于日志记录、评估、RNG、检查点和数据分片,多主机训练可以非常容易引入错误!

  • 确保管道仅在一个主机上进行日志记录和检查点操作。
  • 确保在运行评估或检查点之前,批处理规范统计信息在主机之间同步。
  • 在主机之间具有相同的 RNG 种子(用于模型初始化)和在主机之间具有不同的种子(用于数据洗牌/预处理)至关重要,因此请确保适当地标记它们。
  • 通常建议跨主机分片数据文件以提高性能。

常见问题

什么是最佳学习率衰减时间表系列?

[点击展开]
  • 这是一个悬而未决的问题。目前尚不清楚如何构建一组严格的实验来自信地回答“最佳”LR衰减时间表是什么。
  • 虽然我们不知道最佳时间表系列,但我们相信有一些(非恒定)时间表很重要,并且调整它很重要。
  • 在优化过程中,不同的学习率在不同时间效果最好。拥有某种时间表会使模型更有可能达到良好的学习率。

我应该使用哪种学习率衰减作为默认值?

[点击展开]
  • 我们的偏好是线性衰减或余弦衰减,一堆其他时间表家族可能也很好。

为什么有些试卷的学习率很复杂?

[点击展开]
  • 具有复杂的分段学习率(LR)衰减时间表的论文并不少见。
  • 读者经常想知道作者是如何得出如此复杂的时间表的。
  • 许多复杂的 LR 衰减计划是以临时方式调整计划作为验证集性能函数的结果:
    1. 使用一些简单的 LR 衰减(或恒定学习率)开始单个训练运行。
    2. 继续训练,直到性能似乎停滞不前。如果发生这种情况,请暂停训练。从这一点开始,使用可能更陡峭的LR衰减时间表(或更小的恒定学习率)来恢复它。重复此过程,直到会议/启动截止日期。
  • 轻率地复制生成的计划通常不是一个好主意,因为最好的特定计划将对许多其他超参数选择敏感。
    • 最好复制生成时间表的算法,尽管当任意的人为判断产生时间表时,这几乎是不可能的。
  • 如果可以完全自动化,则可以使用这种类型的验证错误敏感计划,但是作为验证误差函数的人机在环计划很脆弱,不容易重现,因此我们建议避免使用它们。
    • 在使用此类时间表发布结果之前,请尝试使其完全可重现。

应该如何调整亚当的超参数?

[点击展开]
  • 如上所述,对搜索空间以及应该从搜索空间中抽取多少点进行一般性陈述是非常困难的。请注意,并非 Adam 中的所有超参数都同样重要。以下经验法则对应于研究中试验数量的不同“预算”。
    • 如果一项研究中< 10 次试验,则仅调整(基础)学习率。
    • 如果进行 10-25 次试验,请调整学习率和 $\beta_1$。
    • 如果 25+ 次试验,请调整学习率 $\beta_1$ 和 $\epsilon$。
    • 如果可以运行超过 25 个试验,则另外调整 $\beta_2$。

为什么在调优的探索阶段使用准随机搜索而不是更复杂的黑盒优化算法?

[点击展开]
  • 准随机搜索(基于低差异序列)是我们的偏好,而不是更高级的黑盒优化工具,当用作迭代调优过程的一部分时,旨在最大限度地洞察调优问题(我们称之为“探索阶段”)。贝叶斯优化和类似工具更适合开发阶段。
  • 基于随机移动的低差异序列的准随机搜索可以被认为是“抖动,随机的网格搜索”,因为它均匀但随机地探索给定的搜索空间,并且比随机搜索更分散搜索点。
  • 与更复杂的黑盒优化工具(例如贝叶斯优化、进化算法)相比,准随机搜索的优势包括:
    1. 对搜索空间进行非自适应采样可以在事后分析中更改调整目标,而无需重新运行实验。
      • 例如,我们通常希望在训练的任何点上实现验证误差方面找到最佳试验。但是准随机搜索的非适应性使得可以根据最终验证误差、训练误差或一些替代评估指标找到最佳试验,而无需重新运行任何实验。
    2. 准随机搜索的行为一致且统计上可重复。
      • 即使搜索算法的实现发生变化,只要它保持相同的均匀性属性,也应该可以重现六个月前的研究。如果使用复杂的贝叶斯优化软件,则实现可能会在版本之间发生重要变化,从而使重现旧搜索变得更加困难。并不总是可以回滚到旧的实现(例如,如果优化工具作为服务运行)。
    3. 它对搜索空间的统一探索使得更容易推理结果以及它们可能对搜索空间的建议。
      • 例如,如果准随机搜索遍历中的最佳点位于搜索空间的边界,则这是一个很好的(但并非万无一失)的信号,表明搜索空间边界应该改变。本节将更深入地介绍。然而,自适应黑盒优化算法可能会因为一些不幸的早期试验而忽略搜索空间的中间,即使它恰好包含同样好的点,因为一个好的优化算法需要采用这种精确的不均匀性来加速搜索。
    4. 与自适应算法不同,使用准随机搜索(或其他非自适应搜索算法)时,并行与顺序运行不同数量的试验不会产生统计上不同的结果。
    5. 更复杂的搜索算法可能并不总是正确处理不可行的点,特别是如果它们在设计时没有考虑到神经网络超参数调优。
    6. 准随机搜索很简单,当许多调优试验将并行运行时,效果特别好。
      • 有趣的是,自适应算法很难击败预算为2倍的准随机搜索,特别是当许多试验需要并行运行时(因此在启动新试验时很少有机会利用以前的试验结果)。
      • 如果没有贝叶斯优化和其他高级黑盒优化方法的专业知识,我们可能无法实现它们原则上能够提供的好处。很难在真实的深度学习调优条件下对高级黑盒优化算法进行基准测试。它们是当前研究的一个非常活跃的领域,更复杂的算法对于没有经验的用户来说也有自己的陷阱。这些方法的专家能够获得良好的结果,但在高并行性条件下,搜索空间和预算往往更重要。
  • 也就是说,如果我们的计算资源只允许少量试验并行运行,并且我们可以按顺序运行许多试验,那么贝叶斯优化将变得更具吸引力,尽管我们的调优结果更难解释。
[点击展开]
  • 开源 Vizier 实现了准搜索在此用法示例中设置。
    algorithm="QUASI_RANDOM_SEARCH"
  • 此处存在另一种实现。
  • 上述两种实现都为给定的搜索空间生成了一个 Halton 序列(旨在实现 https://arxiv.org/abs/1706.03200 中建议的移位、加扰的 Halton 序列)。
  • 如果没有基于低差异序列的准随机搜索算法可用,则可以替代伪随机均匀搜索,尽管这可能效率略低。
    • 在1-2维中,网格搜索也是可以接受的,尽管不是在更高维度上(见Bergstra&Bengio,2012)。
[点击展开]

显示足够采样重要性的箱形图

图3:ResNet-50在ImageNet上进行了100次试验。通过自举,模拟了不同数量的调优预算。每个试用预算的最佳性能的箱形图如上图所示。

  • 一般没有办法回答这个问题,但我们可以看看具体的例子。
  • 如图3所示,研究中的试验数量会对结果产生重大影响。
    • 请注意,抽样 6 项试验时与抽样 20 项试验时四分位距有多大。
    • 即使有 20 次试验,特别幸运和不幸的研究之间的差异也可能大于该模型在不同随机种子上重新训练的典型差异,具有固定超参数,对于此工作负载,在验证错误率为 ~23% 的情况下,该差异可能约为 +/- 0.1%。

如何调试和缓解优化失败?

[点击展开]

摘要:如果模型遇到优化困难,请务必在尝试其他操作之前修复它们。诊断和纠正培训失败是一个活跃的研究领域。

在 WideResnet 中更改单个残差块中的步幅会导致训练不稳定。

图4:在 WideResnet 中更改单个残差块 (2x2 -> 1x1) 中的步幅会导致训练不稳定。这不会降低低学习率下的表现,但由于不稳定,高学习率不再训练良好。应用 1000 步学习率热身解决了这种特殊的不稳定情况,允许以 .1 的最大学习率进行稳定的训练。

识别不稳定的工作负载

  • 如果学习率太大,任何工作负载都会变得不稳定。只有当不稳定迫使我们使用太小的学习率时,它才是一个问题。
  • 至少有两种类型的训练不稳定值得区分:
    1. 初始化时/训练早期不稳定。
    2. 训练中突然不稳定。
  • 我们可以采取系统的方法来确定工作负载中的稳定性问题。
    1. 进行学习率扫描并找到最佳学习率 lr*。
    2. 绘制略高于 lr* 的学习率的训练损失曲线。
    3. 如果学习率>lr*显示损失不稳定(在训练期间损失上升而不是下降),那么修复不稳定性可能会导致更好的训练。
  • 在训练期间记录完整损失梯度的 L2 范数,异常值可能会导致训练过程中出现杂散不稳定。这可以告知如何选择渐变/更新裁剪。

注意:一些模型显示出非常早期的不稳定,然后恢复导致缓慢但稳定的训练。常见的评估计划可能会因为评估频率不够频繁而错过这些问题!

为了检查这一点,我们可以使用 来训练仅 ~500 步的简短运行,但评估每一步。

lr = 2 * current best

说明在培训开始时进行更频繁评估的价值。

图5:说明在培训开始时进行更频繁评估的价值。如果怀疑模型存在早期训练不稳定,则很有用。

常见不稳定模式的潜在修复

  • 应用学习率预热
    • 最适合早期训练不稳定。
  • 应用渐变剪切
    • 对早期和中期训练不稳定都有好处,可能会修复一些热身无法解决的不良问题。
  • 尝试新的优化器
    • 有时亚当可以处理动量无法处理的不稳定。这是一个活跃的研究领域。
  • 我们可以确保为模型架构使用最佳实践/初始化(下面的示例)。
    • 添加残差连接和规范化(如果模型尚未包含)。
  • 归一化应该是残差之前的最后一个操作。例如 x + 范数(f(x))。
  • 已知会导致问题的规范(x + f(x))。
  • 尝试将残差分支初始化为 0(例如 ReZero init)。
  • 降低学习率
    • 这是最后的手段。

学习率预热

预热期间不稳定的示例(请注意水平轴对数刻度)。

图6:预热期间不稳定的示例(请注意水平轴对数刻度)。在这种情况下,需要 40k 步的热身才能成功训练。

何时应用学习率预热

具有不稳定性的模型的轴图

图 7a:表现出训练不稳定的模型的超参数轴图示例。最好的学习率处于可行的边缘。“不可行”的试验被定义为产生NaN或异常高的损失值的试验。

不稳定模型的损失曲线

图 7b:使用学习率训练的模型的训练损失,我们看到不稳定。

  • 图 7a 显示了一个超参数轴图,该图指示模型遇到优化不稳定,因为最佳学习率正好处于不稳定的边缘。
  • 图 7b 显示了如何通过检查学习率比该峰值大 5 倍或 10 倍的训练模型的训练损失来仔细检查这一点。如果该图显示损失在稳定下降后突然上升(例如,在上图中的步长~10k处),则模型可能会受到优化不稳定的影响。
如何应用学习率热身

热身对训练不稳定性的有益影响

图8:学习率预热对解决训练不稳定性的有益作用。

  • 使用上面的部分,我们假设从业者已经确定了模型变得不稳定的学习率。这是 .
    unstable_base_learning_rate
  • 热身包括预先预置一个学习率计划,将学习率从 0 提高到某个稳定,至少比 大一个数量级。默认是尝试 10x .尽管请注意,可以再次运行整个过程,例如 100x .具体时间表如下:
    base_learning_rate
    unstable_base_learning_rate
    base_learning_rate
    unstable_base_learning_rate
    unstable_base_learning_rate
    • 从 0 上升到超过 。
      base_learning_rate
      warmup_steps
    • 以恒定速率训练 .
      post_warmup_steps
  • 我们的目标是找到允许我们访问远高于 的峰值学习率的最短数量。
    warmup_steps
    unstable_base_learning_rate
  • 所以对于每一个,我们需要调谐和。通常可以设置为 .
    base_learning_rate
    warmup_steps
    post_warmup_steps
    post_warmup_steps
    2*warmup_steps
  • 预热可以独立于现有的衰减时间表进行调整。 应该扫几个不同的数量级。例如,一个示例研究可以尝试[10, 103, 104, 105]。最大可行点不应超过 10%。
    warmup_steps
    max_train_steps
  • 一旦建立了不会爆炸训练的模型,就应该将其应用于基线模型。从本质上讲,我们将此时间表附加到现有时间表之前,并使用上面讨论的最佳检查点选择将此实验与基线进行比较。例如,如果我们最初有 10,000 个步骤,并且执行了 1000 个步骤,则新的训练过程总共应运行 11,000 个步骤。
    warmup_steps
    base_learning_rate
    max_train_steps
    warmup_steps
  • 如果需要长期进行稳定的训练(>5%),可能需要增加以说明这一点。
    warmup_steps
    max_train_steps
    max_train_steps
  • 在整个工作负载范围内,实际上并没有“典型”值。有些型号只需要 100 步,而其他型号(尤其是变压器)可能需要 40k+。

渐变剪切

早期训练不稳定性的梯度裁剪

图 9:梯度裁剪图示纠正早期训练不稳定性。

  • 梯度裁剪在发生较大或异常梯度问题时最有用。
  • 裁剪可以修复早期训练不稳定(早期大梯度范数)或训练中期不稳定(训练中期突然出现梯度峰值)。
  • 有时,较长的预热时间可以纠正剪裁无法纠正的不稳定性:请参阅上面的本节
    • 🤖 热身时剪裁怎么办?
  • 理想的剪切阈值略高于“典型”梯度标准。
  • 下面是如何执行渐变裁剪的示例:
    • 如果梯度的范数 $\left |g \right |$ 大于梯度裁剪阈值 $\lambda$,则执行 ${g}'= \lambda \times \frac{g}{\left | g \right |}$,其中 ${g}'$ 是新的梯度。
  • 在训练期间记录未剪裁的梯度范数。默认情况下,生成:
    • 梯度范数与阶跃的关系图
    • 所有步骤上聚合的梯度范数直方图
  • 根据梯度范数的第 90 个百分位数选择渐变裁剪阈值。
    • 阈值将取决于工作负载,但 90% 是一个很好的起点。如果它不起作用,可以调整此阈值。
    • 🤖 某种适应性策略呢?
  • 如果我们尝试梯度裁剪并且不稳定问题仍然存在,我们可以更努力地尝试(即使阈值更小)。
  • Extremely aggressive gradient clipping is in essence a strange way of reducing the learning rate. If we find ourselves using extremely aggressive clipping, we probably should just cut the learning rate instead.
  • We would usually consider having >50% of the updates getting clipped somehow as "extremely aggressive".
  • If we need to do extremely aggressive gradient clipping to deal with our instability issues, then we might as well reduce the learning rate.

为什么将学习率和其他优化参数称为超参数?它们不是任何先验分布的参数。

[点击展开]
  • 的确,术语“超参数”在贝叶斯机器学习中具有精确的含义,并且将学习率和我们在深度学习中调整的大多数其他参数称为“超参数”是对术语的滥用。
  • 我们更愿意使用术语“元参数”来表示学习率、架构参数以及我们在深度学习中调整的所有其他内容,因为它避免了因滥用“超参数”一词而引起的混淆(在讨论贝叶斯优化时,概率响应面模型有自己的真实超参数时,这种混淆尤其可能)。
  • 不幸的是,尽管可能令人困惑,但术语超参数在深度学习社区中已经变得非常普遍。
  • 因此,对于像本文档这样的文档,面向广泛的受众,包括许多不太可能意识到这种技术性的人,我们选择为该领域的一个混乱来源做出贡献,希望避免另一个。
  • 也就是说,在发表研究论文时,我们可能会做出不同的选择,并且我们会鼓励其他人在大多数情况下使用“元参数”。

为什么不应调整批大小以直接提高验证集性能?

[点击展开]
  • 在不更改训练管道的任何其他详细信息的情况下更改批大小通常会影响验证集性能。
  • 但是,如果针对每个批大小单独优化训练管道,则两个批大小之间的验证集性能差异通常会消失。
  • 与批大小交互最强烈的超参数是优化器超参数(例如学习率、动量)和正则化超参数,因此对于每个批大小分别进行调优最为重要。
    • 由于样本方差,较小的批量大小会给训练算法带来更多的噪声,并且这种噪声可以产生正则化效果。因此,较大的批量大小更容易出现过度拟合,并且可能需要更强的正则化和/或额外的正则化技术。
  • 此外,更改批次大小时,可能需要调整训练步骤的数量
  • 一旦考虑到所有这些影响,目前没有令人信服的证据表明批量大小会影响最大可实现的验证性能(参见Shallue等人,2018)。
[点击展开]

随机梯度下降 (SGD)

$$\theta_{t+1} = \theta_{t} - \eta_t \nabla \mathcal{l}(\theta_t)$$

动量

$$v_0 = 0$$

$$v_{t+1} = \gamma v_{t} + \nabla \mathcal{l}(\theta_t)$$

$$\theta_{t+1} = \theta_{t} - \eta_t v_{t+1}$$

涅斯捷罗夫

$$v_0 = 0$$

$$v_{t+1} = \gamma v_{t} + \nabla \mathcal{l}(\theta_t)$$

$$\theta_{t+1} = \theta_{t} - \eta_t( \gamma v_{t+1} + \nabla \mathcal{l}(\theta_{t})$$

RMSProp

$$v_0 = 1 \text{,} m_0 = 0$$

$$v_{t+1} = \rho v_{t} + (1 - \rho) \nabla \mathcal{l}(\theta_t)^2$$

$$m_{t+1} = \gamma m_{t} + \frac{\eta_t}{\sqrt{v_{t+1} + \epsilon}}\nabla \mathcal{l}(\theta_t)$$

$$\theta_{t+1} = \theta_{t} - m_{t+1}$$

亚当

$$m_0 = 0 \text{,} v_0 = 0$$

$$m_{t+1} = \beta_1 m_{t} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)$$

$$v_{t+1} = \beta_2 v_{t} + (1 - \beta_2) \nabla \mathcal{l}(\theta_t)^2$$

$$b_{t+1} = \frac{\sqrt{1 - \beta_2^{t+1}}}{1 - \beta_1^{t+1}}$$

$$\theta_{t+1} = \theta_{t} - \alpha_t \frac{m_{t+1}}{\sqrt{v_{t+1}} + \epsilon} b_{t+1}$$

纳达姆

$$m_0 = 0 \text{,} v_0 = 0$$

$$m_{t+1} = \beta_1 m_{t} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)$$

$$v_{t+1} = \beta_2 v_{t} + (1 - \beta_2) \nabla \mathcal{l} (\theta_t)^2$$

$$b_{t+1} = \frac{\sqrt{1 - \beta_2^{t+1}}}{1 - \beta_1^{t+1}}$$

$$\theta_{t+1} = \theta_{t} - \alpha_t \frac{\beta_1 m_{t+1} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)}{\sqrt{v_{t+1}} + \epsilon} b_{t+1}$$

确认

  • 我们非常感谢Max Bileschi,Roy Frostig,Zelda Mariet,Stan Bileschi,Mohammad Norouzi,Chris DuBois和Charles Sutton阅读手稿并提供有价值的反馈。
  • 我们重复使用了最初由Naman Agarwal制作的几个地块的一些实验数据,用于其他联合研究。
  • 我们要感谢陈伟对文件的介绍提出的宝贵意见。
  • 我们还要感谢罗汉·阿尼尔的有益讨论。

引用

@misc{tuningplaybookgithub,
  author = {Varun Godbole and George E. Dahl and Justin Gilmer and Christopher J. Shallue and Zachary Nado},
  title = {Deep Learning Tuning Playbook},
  url = {http://github.com/google-research/tuning_playbook},
  year = {2023},
  note = {Version 1.0}
}

贡献

  • 这不是官方支持的 Google 产品。

  • 我们很乐意听到你的反馈!

    • 如果你喜欢剧本,请留下一颗星星!或者通过电子邮件发送深度学习调优手册 [at] googlegroups.com。推荐可以帮助我们证明创建更多这样的资源的合理性。
    • 如果有任何不正确的地方,请提交问题以开始讨论。对于问题不合适的问题或其他消息,请在 GitHub 上打开新的讨论主题。
  • 正如序言中所讨论的,这是一份活的文件。我们预计将定期进行大大小小的改进。如果你希望收到通知,请观看我们的存储库(请参阅说明)。

  • 请不要在未首先通过问题跟踪系统与作者协调的情况下提交拉取请求。

贡献者许可协议

对本项目的贡献必须附有贡献者许可协议 (CLA)。你(或你的雇主)保留你贡献的版权;这只是允许我们使用和重新分发你的贡献作为项目的一部分。前往 https://cla.developers.google.com/ 查看你当前存档的协议或签署新协议。

你通常只需要提交一次 CLA,因此如果你已经提交了 CLA(即使是针对其他项目),你可能不需要再次提交。

代码审查

所有提交,包括项目成员提交的内容,都需要审核。为此,我们使用 GitHub 拉取请求。有关使用拉取请求的更多信息,请参阅 GitHub 帮助

社区准则

该项目遵循谷歌的开源社区准则

  1. Ben Recht和Kevin Jamieson指出,作为基线,2倍预算随机搜索是多么强大(Hyperband论文提出了类似的论点),但肯定有可能找到搜索空间和问题其中最先进的贝叶斯优化技术粉碎了预算2倍的随机搜索。然而,根据我们的经验,在高并行性制度中击败 2X 预算随机搜索变得更加困难,因为贝叶斯优化没有机会观察先前试验的结果。