Guide for starting a new project
翻译整理自google-research/tuning_playbook
开展一个新项目的指南
摘要: 我们在调整过程中做出的许多决定可以在项目开始时一次性做出,只有在情况发生变化时才偶尔重新审视。
我们的指导假定以下内容:
- 已经完成了问题制定、数据清理等基本工作,花时间调整模型架构和训练配置是有意义的。
- 已经设置了一个可以进行训练和评估的流水线,并且可以轻松执行感兴趣的各种模型的训练和预测任务。
- 已经选择并实施了适当的指标。这些指标应尽可能反映部署环境中测量的内容。
选择模型架构
摘要: 在开始一个新项目时,尝试重用一个已经有效的模型。
- 首先选择一个成熟、常用的模型架构以获得有效的工作。总是可以稍后构建自定义模型。
- 模型架构通常具有各种超参数,用于确定模型的大小和其他细节(例如层数、层宽、激活函数类型)。
- 因此,选择架构实际上意味着选择一个不同模型的家族(每个对应一种模型超参数设置)。
- 我们将在Choosing the initial configuration and A scientific approach to improving model performance中考虑选择模型超参数的问题。
- 如果可能,尝试找到一篇尽可能接近手头问题的论文,并将其作为起点进行复现。
选择优化器
摘要: 从手头问题类型的最流行优化器开始。
没有优化器是所有机器学习问题和模型架构的“最佳”优化器。即使只是比较优化器的性能也是一项艰巨的任务。🤖
我们建议坚持使用成熟、流行的优化器,特别是在开始新项目时。
- 理想情况下,请选择用于同一类型问题的最流行优化器。
准备关注所选优化器的所有超参数。
具有更多超参数的优化器可能需要更多的调整工作才能找到最佳配置。
在项目的初始阶段,当我们试图找到其他各种超参数的最佳值时(例如架构超参数),将优化器超参数视为干扰参数 (Nuisance hyperparameters),这是非常重要的。
(Nuisance hyperparameters是未被特定,但是在理论测试时被考虑到的那些,即它们是需要优化以便比较科学超参数(Scientific hyperparameters) 的不同值的参数。科学超参数是我们试图衡量它们对模型性能造成的影响的参数。
在项目的初始阶段,可能更喜欢使用更简单的优化器(例如具有固定动量的SGD或具有固定ϵ、β1和β2的Adam),然后稍后切换到更一般的优化器。
我们喜欢的成熟优化器(但不限于)包括:
- 带有动量的SGD(我们喜欢Nesterov变体)
- Adam和NAdam,它们比带有动量的SGD更一般。请注意,Adam具有4个可调超参数它们都很重要!
- 请参阅[Adam的超参数如何调整?]
- 根据上面的讨论,关于搜索空间以及应该从搜索空间中采样多少点的一般性陈述是非常困难的。请注意,Adam中的所有超参数并不都同样重要。以下经验法则对应于不同的“预算”,用于研究中的试验次数。 - 如果研究中的试验次数少于10次,只调整(基本)学习率。 - 如果10-25次试验,调整学习率和β1。 - 如果25+次试验,调整学习率,β1和ϵ。 - 如果可以运行的试验次数大大超过25次,还可以调整β2。
选择批量大小
摘要: 批量大小控制训练速度,不应该用来直接调整验证集性能。通常,理想的批量大小将是可用硬件支持的最大批量大小。
- 批量大小是确定训练时间和计算资源消耗的关键因素。
- 增加批量大小通常会减少训练时间。这可能是非常有益的,因为它:
- 允许在固定的时间间隔内更彻底地调整超参数,可能导致更好的最终模型。
- 减少开发周期的延迟,允许更频繁地测试新想法。
- 增加批量大小可以减少、增加或不改变资源消耗。
- 批量大小不应该被当作用于验证集性能的可调超参数。
- 只要所有超参数都得到很好的调整(特别是学习率和正则化超参数),并且训练步数足够,使用任何批量大小都应该可以获得相同的最终性能(请参见 Shallue et al. 2018 )。
- 请参阅为什么不应该将批量大小调整为直接改善验证集性能?
- 改变批量大小而不改变任何其他训练管道的细节通常会影响验证集性能。
- 但是,如果为每个批量大小单独优化训练管道,两个批量大小之间的验证集性能差异通常会消失。
- 与批量大小最强烈相互作用的超参数,因此对于每个批量大小最重要的是单独调整优化器超参数(例如学习率,动量)和正则化超参数。
- 较小的批量大小会由于样本方差向训练算法引入更多噪声,并且此噪声可能具有正则化效果。因此,较大的批量大小可能更容易过度拟合,可能需要更强的正则化和/或额外的正则化技术。
- 此外,改变批量大小时,可能需要调整训练步骤的数量。
- 一旦考虑到所有这些影响,目前尚无令人信服的证据表明批量大小会影响最大可达到的验证性能(参见Shallue et al. 2018)。
确定可行的批量大小和估计训练吞吐量
- 对于给定的模型和优化器,可用硬件通常会支持一定范围的批量大小。限制因素通常是加速器内存。
- 不幸的是,在不运行或者至少不编译整个训练程序的情况下计算哪些批量大小将适合内存可能很困难。
- 最简单的解决方案通常是运行不同批量大小(例如增加2的幂)的训练作业,直到其中一个作业超过可用的内存为止。
- 对于每个批量大小,我们应该训练足够长的时间来获得训练吞吐量的可靠估计
训练吞吐量 =(#每秒处理的实例)
或者,等效地,每步时间。
每步时间 =(批量大小)/(训练吞吐量)
- 当加速器尚未饱和时,如果批量大小翻倍,训练吞吐量也应该翻倍(或者至少接近翻倍)。等效地,每步时间随着批量大小的增加应该是恒定的(或者至少接近恒定)。
- 如果情况不是这样,那么训练管道就具有瓶颈,例如I / O或计算节点之间的同步。在继续之前,这可能值得诊断和纠正。
- 如果训练吞吐量仅增加到某个最大批量大小,邤我们应该只考虑到该最大批量大小,即使硬件支持更大的批量大小。
- 使用较大批量大小的所有好处均假定训练吞吐量会增加。 如果不是,修复瓶颈或使用较小的批量大小。
- 梯度累积模拟比硬件支持的更大的批量大小,因此不提供任何吞吐量优势。 在应用工作中通常应避免使用它。
- 每次更改模型或优化器时(例如,不同的模型架构可能允许更大的批量大小适合内存),可能需要重复这些步骤。
选择批量大小以最小化训练时间
训练时间 =(每步时间)x(总步数)
我们通常可以认为每步时间对于所有可行的批量大小来说都是近似恒定的。 当没有并行计算的开销并且所有训练瓶颈都已经诊断和纠正(请参阅上一节以了解如何识别训练瓶颈)时,这是正确的。 实践中,随着批量大小的增加,通常至少有一些开销。
随着批量大小的增加,要达到固定性能目标所需的总步数通常会减少(所有相关超参数在更改批量大小时重新调整; Shallue et al. 2018)。
- 例如。 将批量大小翻倍可能会使所需的总步数减半。 这称为完美缩放。
完美缩放适用于所有批量大小,直到一个临界批量大小,超出该批量大小,收益就会逐渐减少。
- 最终,增加批量大小不再减少训练步骤的数量(但永远不会增加)。
因此,最小化训练时间的批量大小通常是仍然提供减少训练步骤数量的最大批量大小。
此批量大小取决于数据集,模型和优化器,除了为每个新问题找到它的实验之外,如何计算它是一个未解决的问题。 🤖
在比较批量大小时,要注意示例预算/epoch预算(固定训练示例呈现的数量来运行所有实验)和步骤预算(固定训练步骤的数量来运行所有实验)之间的区别。
- 使用epoch预算比较批量大小只探测完美缩放模式,即使更大的批量大小仍然可以通过减少所需的训练步骤来提供有意义的加速。
通常,可用硬件支持的最大批量大小小于关键批量大小。因此,一个很好的经验法则(无需运行任何实验)是使用尽可能大的批量大小。
如果使用更大的批量大小会增加训练时间,那么没有必要使用更大的批量大小。
选择批量大小以最小化资源消耗
- 增加批量大小与之相关的资源成本有两种类型:
- 预付费用,例如购买新硬件或重写训练管道以实现多GPU/多TPU训练。
- 使用费用,例如对团队资源预算进行计费,云提供商收费,电费/维护费用。
- 如果增加批量大小会带来显着的前期成本,那么最好推迟增加批量大小,直到项目已成熟,并且更容易评估成本效益权衡。 实施多主机并行训练程序可能会引入错误和微妙的问题,因此可能最好从一个更简单的管道开始。(另一方面,训练时间的大幅加速可能在大量调整实验需要时很有益。)
- 我们将总使用成本(可能包括多种不同类型的成本)称为“资源消耗”。 我们可以将资源消耗分解为以下组件:
资源消耗=(每步资源消耗)x(总步数)
- 增加批量大小通常允许我们减少总步数。 资源消耗是增加还是减少将取决于每步消耗如何改变。
- 增加批量大小可能会减少资源消耗。 例如,如果使用较大批量大小的每个步骤都可以在与较小批量大小相同的硬件上运行(仅每步时间稍有增加)
- 增加批量大小可能不会改变资源消耗。例如,如果将批量大小翻倍,可以减少所需步骤的一半,并使用两倍的GPU,总消耗(以GPU小时为单位)将不会改变。
- 增加批量大小可能会增加资源消耗。例如,如果增加批量大小需要升级硬件,每步的消耗增加可能会超过步骤数量的减少。
更改批量大小需要重新调整大多数超参数
- 大多数超参数的最佳值对批量大小敏感。 因此,更改批量大小通常需要重新开始调整过程。
- 与批量大小最密切相关的超参数,因此最重要的是为每个批量大小单独调整,是优化器超参数(例如学习率,动量)和正则化超参数。
- 在选择项目开始时的批量大小时要牢记这一点。 如果您稍后需要切换到不同的批量大小,则重新调整所有内容以适应新批量大小可能很困难,耗时且昂贵。
批量归一化如何与批量大小交互
批量归一化很复杂,一般来说,应该使用不同于梯度计算的批量大小来计算统计信息。 有关详细讨论,请参见批量归一化部分
选择初始配置
- 在开始超参数调整之前,我们必须确定起点。 这包括指定(1)模型配置(例如层数),(2)优化器超参数(例如学习率)以及(3)训练步骤数。
- 确定此初始配置将需要一些手动配置的训练运行和试错。
- 我们的指导原则是找到一个简单,相对快速,相对低资源消耗的配置,可以获得“合理”的结果。
- “简单”意味着尽可能避免花哨的东西;这些都可以稍后添加。 即使花哨的东西最终证明有帮助,在初始配置中添加它们也会浪费时间来调整无用的功能,或者合并不必要的复杂性。
- 例如,先使用恒定的学习率,然后再添加花哨的衰减计划。
- 选择快速且资源消耗最小的初始配置将使超参数调整更加高效。
- 例如,从较小的模型开始。
- “合理”的性能取决于问题,但至少意味着训练的模型在验证集上的表现要好得多,比随机机会好(尽管它可能足够糟糕,不值得部署)。
- “简单”意味着尽可能避免花哨的东西;这些都可以稍后添加。 即使花哨的东西最终证明有帮助,在初始配置中添加它们也会浪费时间来调整无用的功能,或者合并不必要的复杂性。
- 选择训练步骤数量涉及以下考量:
- 一方面,训练更多步骤可以提高性能,并使超参数调整更容易(请参见Shallue et al. 2018)。
- 另一方面,训练步骤较少意味着每次训练运行更快,使用的资源更少,通过减少周期之间的时间来提高调整效率,并允许并行运行更多实验。此外,如果最初选择了不必要的大步骤预算,则可能很难在以后更改它,例如一旦为该步数调整了学习率计划。