调参与训练

1 传统机器学习

1.1 XGBoost

最常用的10个超参数(原生API,兼容Scikit-learn的API,常见取值范围):

  • num_boost_round:训练期间所需要的基学习器数量,默认100;在应对较大数据集时,一般控制在5000~10000左右(影响训练时间的重要因素);一个常用技巧是先设定一个较高的数值,然后结合early-stopping来获得一个较优的模型版本;
  • eta:较大的学习率会给集合中每棵树的贡献赋予了更大的权重,加快训练时间,但可能导致过拟合/不稳定;而较低的学习率会抑制了每棵树的贡献,使学习过程更慢但更健壮
  • max_depth:控制决策树在训练过程中可能达到的最大层次数;更深的树可以捕获特征之间更复杂的相互作用,但也有更高的过拟合风险;限制max_depth,从而生成更浅、更简单的树,并捕获更通用的模式。
  • subsample:在随机选择的部分数据上进行训练,从而有助于对抗过拟合;使用较小的值降低了树之间的相关性,增加了集合中的多样性,有助于提高泛化和减少过拟合
  • colsample_bytree:控制每个决策树将使用的特征的比例,类似于subsample;较大的值会增加树之间的相关性,降低多样性并可能导致过拟合
  • gamma:作为一个阈值来决定一个叶节点是否应该进一步分割;调优的目标是找到导致损失函数最大减少的最佳分割,这意味着改进的模型性能
  • min_child_weight:每个节点中的最小实例数,防止过拟合
  • lambda:L2正则化参数,压缩不重要特征的权重,降低模型复杂性,避免过拟合
  • alpha:L1正则化参数,类似于lambda;更高的alpha或lambda值可能需要调整其他参数来补偿增加的正则化。例如,较高的alpha值可能受益于较大的subsample值,因为可以保持模型多样性并防止欠拟合

2 深度学习

2.1 优化器

前置理论:常见的梯度下降法族

优化器的选择:

  • 针对手头问题类型,选择最常用的优化器开始
  • 自适应梯度方法的性能一般不会低于动量或梯度下降
  • 常用的优化器包括(但不限于)动量法、Adam和NAdam
  • 个人偏好的学习率衰减方案是linear decay或cosine decay

主流优化器的性能表现(Figure 1)与训练速度(Figure 2):

Adam超参数调整的经验性总结:

  • 如果在一次研究中,训练次数试验次数小于10,那么只需要对基本学习率进行调整。
  • 如果试验次数在10到25次之间, 那么需要对学习率以及$\beta_1$进行调整。
  • 如果试验次数在25次以上,那么需要对学习率、 $\beta_1$以及$\epsilon$进行调整。
  • 如果可以运行的试验次数大于25次,还需要额外调整$\beta_2$

2.2 BatchSize

Batch Size的选择:可用硬件支持的最大Batch Size

  • Batch Size是决定训练时间和计算资源消耗的关键因素
  • 增加Batch Size通常会减少训练时间(减少开发周期,降低调参成本)
  • Batch Size的取值一般按照2的幂次逐步增大,直到找到硬件支持的最大Batch Size
  • 随着Batch Size的增大,训练时间会先等比缩小,然后边际效用递减,直至作用消失
  • 只要调整好所有超参数(尤其是学习率和正则化超参数)并且训练步数足够,理论上任意的Batch Size都能获得相同的最终性能(参见 Shallue et al. 2018

为什么不应该调整Batch Size来直接提高验证集性能?

  1. 目前还没有任何能够令人信服的证据表明batch size会影响最大可实现的验证性能

  2. 在不更改训练工作流其他细节的情况下, 修改batch size 通常会影响验证集的性能;所以更改Batch Size往往需要重新调整大多数超参数(尽量在早期确定下来)

  3. 由于样本方差的原因,较小的batch size会在训练算法中引入更多的不确定性,并且这些不确定性可能存在着正则化效果。反之,较大的batch size可能导致过度拟合,进而需要额外的正则化

2.3 max_train_steps

有两种类型的工作模式:受计算限制的和不受计算限制的

受计算限制:

  • 在某些情况下,训练误差会一直改善,此时耐心和计算资源就成为了限制因素
  • 较短的训练时间内得出的结论可能不能完全适用于长时间训练后的模型
  • 可以延长训练时间或提高训练效率,并且通过适当的调整,改善验证损失
  • 建议在每轮调整中逐渐增加训练步数限制,以在有限的资源和耐心内获得最大的问题理解和目标验证,并在最终长时间训练后再进行验证和确认(用耐心和时间换计算资源)

不受计算限制:

  • 慷慨的训练时间预算可以使调整更容易,以实现良好的训练效果
  • 训练时间更长可能会略微减少训练误差,但不会显着减少验证误差
  • 通过设置检查点(checkpoints)可以避免在训练步数的数量上过度浪费
  • 在某些时候,训练更长的时间并没有多大帮助(甚至会导致过拟合)
  • 模型架构或数据发生变化时(例如数据增强),理想的训练的step数也会发生变化

导致训练时长过长的原因:Batch Size过小、数据增强、特定正则化(如dropout)

2.4 模型迭代优化策略

总结:从简单到复杂、循序渐进、改进有据可依、避免不必要的复杂度

迭代优化策略四步走

  1. 为下一轮实验确定适当的目标(限定明确而足够小的目标范围)
  2. 设计(实验变量、搜索空间、实验次数、搜索算法)并展开实验,朝着这个目标(在优化掉冗余超参数的情况下,使用目标超参数的不同值运行训练流程并对比)取得进展
  3. 从实验结果中获取经验(验证最初的目标,挖掘其他见解,排查问题清单)
  4. 考虑是否上线新的最佳配置(前提:理解导致结果中不同的变化的来源)

细节1 - 深入理解问题:

  • 避免仅因历史原因而表现良好的不必要更改
  • 确定验证集效果对哪些超参数最敏感,哪些超参数交互最多,因此需要一起重新调整,以及哪些超参数对其他变化相对不敏感,因此可以在未来的实验中固定住
  • 发现潜在的新方向,例如在出现过拟合问题时使用新的正则化器
  • 确定无效的方向并将其删除,从而降低后续实验的复杂度
  • 判断超参数的优化空间是否已经饱和
  • 围绕最佳值缩小我们的搜索空间,以提高调整效率

细节2 - 识别目标超参数、冗余超参数和固定超参数

  • 目标超参数是指,我们希望测量出其对于模型由何种影响的参数
  • 冗余超参数是指,必须优化才能公平比较不同目标超参数值的参数
  • 固定超参数是指,在当前轮次实验中取固定值的参数,值不需要/不希望改变
  • 一个超参数是目标超参数、冗余超参数还是固定超参数是根据实验目标来决定的
  • 比如,激活函数的选择可以是一个目标超参数(对于当前问题,ReLU 或 tanh 是更好的选择吗?),一个冗余超参数(允许使用不同的激活函数,最好的 5 层模型是否优于最好的 6 层模型?),或一个固定超参数(对于一个由 ReLU 构成的网络,在特定位置添加批标准化是否有帮助?)
  • 优化器超参数(例如学习率、动量、学习率调度参数、Adam优化器的beta等)或者正则化超参数,至少有一些是冗余超参数;优化器类型、是否使用正则化技术通常是目标超参数或固定超参数;模型结构超参数通常是目标或固定超参数

细节3 - 平衡实验的信息量和成本

  • 在设计研究时,合理分配有限的预算,确保能从实验中获得足够多的经验
  • 冗余超参数需要充分搜索足够大的空间,以公平地比较目标超参数
  • 每个问题都有自己的特性和计算资源限制,借助领域专业知识来节省资源
  • 推荐在探索阶段使用Quasi-Random-Search搜索超参数空间;而在理解问题或确定基本的实验目标后,再考虑使用诸如贝叶斯优化等黑盒优化方法进行更合理的参数搜索

基于随机移动的低差异序列的Quasi-Random-Search可以被认为是“抖动的、打乱的网格搜索”,因为它统一但随机地探索给定的搜索空间,并且搜索点更为分散;Quasi-Random-Search 试验效率高,搜索全面,计算资源消耗低。更多分析细节算法实现

细节4 - 分析实验结果时的排查问题清单

  • 搜索空间够大吗?(最佳的采样点不应该出现在搜索空间的边界)
  • 是否从搜索空间中采样了足够多的点?(可以考虑可视化超参与目标值的关系)
  • 每项研究中有多少试验是不可行(即出现分歧、结果糟糕甚至无法运行的试验)?(检查训练曲线是识别常见故障的一种简单方法)
  • 模型是否存在优化问题?可以从最佳试验的训练曲线中学到什么?

常见不稳定模式的潜在修复方式:学习率预热(适用于早期训练不稳定的情况)、梯度截断、新的优化器、残差连接/归一化、残差调控因子初始化为 0、降低学习率(最终手段)

细节5 - 几种可能导致结果不一致的原因来源

  • 训练程序方差(Training procedure variance)、再训练方差(retrain variance)或试验方差(trial variance):使用相同的超参数但不同的随机种子的训练运行之间看到的差异,试验方差还可能来自训练数据的shuffles、dropout掩码、数据增强操作的模式和并行运算的顺序
  • 超参数搜索方差(Hyperparameter search variance)或学习方差(study variance):由超参数的选择引起的程序结果变化,比如不同的搜索算法或搜索随机种子
  • 数据收集(Data collection)和抽样方差(sampling variance):训练数据、验证数据和测试数据的随机分割所产生的方差,或者更普遍的由于训练数据生成过程而产生的方差

2.5 训练管道优化技巧

技巧1:优化输入管道

  • 使用适当的性能分析工具来诊性能受限的输入管道,例如,用于 JAX 的 Perfetto 或用于 TensorFlow 的 TensorFlow profiler;避免IO延迟和实时预处理的昂贵成本
  • 更广泛的工程考虑(如减少磁盘空间占用)可能会导致较差的输入管道性能
  • 考虑使用 tf.data.Dataset.prefetch 之类的工具对输入管道预读取数据
  • 删除不必要的特征和元数据;使用 tf.data service 增加管道生成数据的进程

技巧2:评估模型性能

  • 使用比训练时更大的 batch size 进行评估;可考虑通过数据抽样减少评估成本
  • 在训练期间定期进行评估,以实时监控其进度;在固定步长间隔进行评估,而不是固定的时间间隔。(注:如100个epoch评估一次,而不是10分钟评估一次)
  • 保存检查点(checkpoints)并追溯选择最佳检查点;提前设定好实验跟踪的目标

技巧3:BatchNorm的实现细节

  • Batch norm 使用当前批次的均值和方差对激活值进行归一化
  • 目前Batch Norm通常可以用Layer Norm代替
  • 但在不能替换的情况下,在更改批大小或主机数量时会有一些棘手的细节

技巧4:多主机管道的考虑因素

  • 保证管道只在一台主机上进行日志记录和检查点
  • 确保在运行评估或检查点之前,批处理规范统计信息在主机之间同步
  • 保证在多主机之间使用相同的随机数生成器种子(用于模型初始化)和不同的种子(用于数据混洗和预处理)是非常重要的,因此请确保合适地标记它们
  • 为了提升性能,通常建议将数据文件在多台主机之间进行分片

参考

XGBoost超参数调优指南
Deep Learning Tuning Playbook
深度学习调优指南中文版

往年同期文章