《深度学习调优指南.系统性优化模型》中文版

2023-09-04 11:55:22 浏览数 (1)

提高模型性能的科学方法

机器学习开发的最终目标是最大化模型的效用。尽管不同应用场景的开发流程有所不同(例如时间长度、可用计算资源、模型类型等),基本步骤和原则都是相似的。

接下来的指南中我们做出了这些假设:

  • 已有能运行且得到不错结果的训练工作流。
  • 有足够的计算资源来进行调参实验,至少能够并行发起数个训练流程。

增量调整策略

总结从简单的配置开始,循序渐进,同时进一步了解问题。确保任何改进都有据可循,以避免增加不必要的复杂度。

  • 我们的最终目标是找到一种训练配置来最大化我们模型的性能。
    • 在某些情况下,我们的目标是在固定截止日期(例如提交给竞赛)之前最大限度地改进模型。
    • 在其他情况下,我们希望无限期地改进模型(例如,不断改进生产中使用的模型)。
  • 原则上,我们可以使用算法自动搜索整个配置空间来最大化性能,但实践中这往往不实际。
    • 配置空间可能非常大,目前还没有任何算法可以在没有人工指导的情况下有效地搜索这个空间。
  • 大多数自动搜索算法依赖于人工设计的搜索空间,这些搜索空间往往非常重要。
  • 更有效的方法是从简单的配置开始,逐步添加功能并进行改进,同时深化对问题的理解。
    • 我们在每一轮调整中都使用自动搜索算法,并随着我们理解的深度不断更新我们的搜索空间。
  • 随着我们的探索,我们自然会找到越来越好的配置,因此我们的“最佳”模型将不断改进。
    • 当我们更新我们的最佳配置时,我们称之为上线(这不一定对应线上模型的实际上线)。
    • 对于每次上线,我们必须确保更改是有据可循的——而不仅仅是碰运气找到的配置——以避免给训练工作流增加不必要的复杂性。

综上所述,我们的增量调优策略需要重复以下四个步骤:

  1. 为下一轮实验确定适当的目标。
  2. 设计并展开实验,朝着这个目标取得进展。
  3. 从实验结果中获取经验。
  4. 考虑是否上线新的最佳配置。

本节的其余部分将更详细地讲解增量调优策略。

探索与利用

总结大多数时候,我们的目标是更深入地理解问题。

  • 尽管有些人认为我们会花大部分时间来提升验证集的指标,实际上我们把重心放在进一步理解问题上,而不是降低验证集错误率。
    • 也就是说,我们大部分时间都花在了“探索”上,只有一小部分时间花在了“利用”上。
  • 从长远来看,如果我们想最大化我们的最终效果,深入理解问题是至关重要的。将深化理解置于短期收益之上可以帮助我们:
    • 避免仅因历史原因而表现良好的不必要更改。
    • 确定验证集效果对哪些超参数最敏感,哪些超参数交互最多,因此需要一起重新调整,以及哪些超参数对其他变化相对不敏感,因此可以在未来的实验中固定住。
    • 发现潜在的新方向,例如在出现过拟合问题时使用新的正则化器。
    • 确定无效的方向并将其删除,从而降低后续实验的复杂度。
    • 判断超参数的优化空间是否已经饱和。
    • 围绕最佳值缩小我们的搜索空间,以提高调整效率。
  • 最终,我们可以集中提升验证集效果,即便我们无法从新的实验中进一步了解问题的结构了。

选择下一轮实验的目标

总结每轮实验都应该有一个明确的目标,并且范围要足够小,这样实验才能真正朝着目标取得进展。

  • 每轮实验都应该有一个明确的目标,并且范围要足够小,这样实验才能真正朝着目标取得进展:如果我们试图一次添加多个特征或回答多个问题,我们可能无法理清各自的影响。
  • 举个例子,目标可以包括:
    • 尝试对训练流程进行改进(例如,新的正则化器、预处理方法等)。
    • 了解特定模型超参数(例如激活函数)的影响
    • 最大化验证集指标。

设计下一轮实验

总结根据实验目标,将超参数分为三类:目标超参数、冗余超参数和固定超参数。创建一系列研究以比较目标超参数的不同值,同时优化冗余超参数。注意选择冗余超参数的搜索空间,以平衡资源成本与科学价值。

识别目标超参数、冗余超参数和固定超参数

[点击展开]

  • 对于给定的目标,所有超参数都将是目标超参数、冗余超参数或固定超参数。
    • 因为实验固定了某些超参数,从实验得出的结论可能对固定超参数的其他值无效。换句话说,固定的超参数对我们的实验结论做了限定。
    • 目标超参数是指,我们希望测量出其对于模型由何种影响的参数。
    • 冗余超参数是指,必须优化才能公平比较不同目标超参数值的参数。类似于统计中的冗余参数。
    • 固定超参数是指,在当前轮次实验中取固定值的参数。在比较目标超参数的不同值时,固定超参数的值不需要(或者我们不希望它们)改变。
  • 举个例子,如果我们的目标是“确定更深的模型是否会减少验证集错误”,那么模型层数就是目标超参数。
    • 学习率是一个冗余超参数,如果我们要公平对比不同深度的模型,我们必须分别调整学习率(通常情况下最优学习率和模型结构有关)。
    • 激活函数是一个固定超参数。我们可能通过过去的实验发现最优激活函数和模型深度无关。或者我们接受实验得到的最优深度的仅在某个激活函数上有效。或者我们也可以将激活函数作为一个冗余超参数和深度一起调优。
  • 一个超参数是目标超参数、冗余超参数还是固定超参数是根据实验目标来决定的。
    • 比如,激活函数的选择可以是一个目标超参数(对于当前问题,ReLU 或 tanh 是更好的选择吗?),一个冗余超参数(允许使用不同的激活函数,最好的 5 层模型是否优于最好的 6 层模型?),或一个固定超参数(对于一个由 ReLU 构成的网络,在特定位置添加批标准化是否有帮助?)。
  • 在设计新一轮实验时,我们根据实验目的确定目标超参数。
    • 在此阶段,我们将所有其他超参数视为冗余超参数。
  • 接下来,我们将一些冗余超参数转作为固定超参数。
    • 一个冗余超参数和目标超参数的相互影响越多,固定这个参数所带来的限制就越多。例如,权重衰减强度的最佳值通常取决于模型大小,因此固定权重衰减的强度来比较不同的模型大小,往往得不出有效的结论。
    • 如下文所述,我们可以通过增加计算资源来应对这种风险,但通常我们的最大资源预算低于调整所有非目标超参数所需的计算资源。
    • 如果有无限的计算资源,我们会将所有非目标超参数保留为冗余超参数,这样我们从实验中得出的结论就不会受到固定超参数的限定。
    • 然而,冗余超参数越多,我们没能充分针对每个目标超参数调优冗余超参数的风险就越高,从而我们从实验中得出错误结论的风险也越高。
    • 当我们判断将一个冗余超参数转换为固定超参数所带来的限制少于调优它所需的计算资源时,我们可以进行这种转换。
  • 尽管超参数的类型取决于实验目标,但对于某些类别的超参数,我们有以下经验法则:
    • 例如,网络层数通常是一个目标或固定的超参数,因为它往往会对训练速度和内存使用产生巨大影响。
    • 例如,dropout 增加了代码的复杂性,因此在决定是否包含它时,我们会将“no dropout”与“dropout”作为一个目标超参数,而将 dropout 率作为一个冗余超参数。
    • 如果我们决定根据这个实验将 dropout 添加到我们的训练流程中,那么在未来的实验中,dropout 率将是一个冗余超参数。
    • 如果我们的实验目标涉及在两个或多个不同的优化器之间进行公平比较(例如“确定哪个优化器在给定的步数中产生最低的验证错误”),那么它就是一个目标超参数。
    • 或者,我们可能出于各种原因将其设为固定超参数,包括(1)先前的实验表明最好的优化器和当前的目标超参数无关;(2)当前优化器的训练曲线更容易理解 (3) 当前优化器比其他优化器使用更少的内存。
    • 它们很少是目标超参数,因为像“训练流程的最佳学习率是多少?”这样的目标没有什么意义——最优学习率很容易随着下一次训练流程的改变而改变。
    • 尽管当资源有限或有强力的证据表明它们不影响目标超参数时,我们可能固定其中一些参数,但通常应该假设优化器超参数必须单独调整,以在不同设置之间进行公平比较目标超参数。
    • 此外,我们没有优化器超参数值的先验倾向(例如,它们通常不会以任何方式影响前向传递或梯度的计算成本)。
    • 在各种优化器超参数(例如学习率、动量、学习率调度参数、Adam优化器的beta等)中,至少有一些是冗余超参数,因为它们往往与其他变化相互影响。
    • 相比之下,优化器的选择通常是一个目标超参数或固定超参数。
    • 正则化技术引入的超参数通常是冗余超参数,但是否使用正则化技术往往是目标或固定超参数。
    • 模型结构超参数通常是目标或固定超参数,因为模型结构变化会影响服务和训练成本、延迟和内存需求。
  • 在某些情况下,一个超参数是冗余还是固定超参数将取决于目标超参数的值。
    • 例如,假设我们想知道 Nesterov momentum 和 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"不同的条件超参数. 它在两种算法中的作用相似(尽管不完全相同),但在每个优化器中运行良好的值范围通常相差几个数量级。

0 人点赞