我们知道,在深度学习中有两类基本的参数:模型参数(Model Parameters)和超参数(Hyperparameters),它们都对模型训练的结果有非常重要的影响。有些研究表明,对于超参数的选择不仅能够影响模型训练的质量好坏,而且也在一定程度上决定了模型训练需要耗费的时间以及内存资源的需求总量。甚至在一些深度模型训练过程中证明,超参数的选择比模型本身的参数更重要,影响也更大。
可见,超参数选择是否合理,直接影响了企业开发并使用模型的成本,所以在深度学习应用领域,业界已经把超参数调优作为开发深度学习应用流程中一个不可或缺的步骤。这样我们就能够把超参数调优解耦成一个独立的组件或模块,然后聚焦该组件的核心能力去做更多探索尝试,最终实现整个深度学习应用开发的业务目标,同时获得了灵活的开发模式,也具有较低的成本优势。
什么是超参数
超参数是指一类静态的参数,这些参数在模型训练之前被定义和设置,而且无法从给定的训练数据中进行学习估计。在模型训练算法中会存在很多超参数,少的话有几个,多的话可能达到几十成百上千个。下面,我们列出一些深度学习模型训练中比较常见的超参数:
- 神经网络深度:搭建的神经网络架构有多少层
- 神经元数:某一层设置多少个节点
- 模型优化器:选择使用哪个优化器,比如 SGD、Adam 等等
- 迭代次数:epochs 设置为迭代多少次
- Loss Function:选择哪个 loss function
- 学习率:学习率大小,是固定的还是动态变化的
- 激活函数:选择一个激活函数,如 Tanh、Sigmoid、ReLU、LeakyReLU 等等
- 正则化方法:L1 正则,还是 L2 正则
- 训练数据批量大小:batch size
如此多的超参数,选择不同的值都会使模型训练的结果不同,那么我们很容易想到将所有的超参数的取值进行组合,然后选择使模型训练结果最优的那一个超参数组合。这对我们来说是非常直观的做法,但是这样的粗暴组合超参数会产生组合爆炸,甚至在如此巨大的超参数组合空间中穷举都是不可能的。这就是超参数调优需要做的事情,它有一套可用的方法,也有一些寻找最优超参数的算法。
超参数调优
超参数调优(HyperParameters Tuning,HPT),又称超参数优化(HyperParameters Optimization,HPO),是指通过找到一个超参数的组合以使得模型训练的 Train Loss 最小,Train Loss 是通过预先为模型定义的 loss function 经过对模型进行迭代训练得到的。
超参数调优的基本流程,如下图所示:
根据上图中,我们给出了三个粒度较粗的组件:超参数调优组件、模型训练组件、模型评估组件,他们是超参数调优过程中最关键的部分。
超参数调优的过程,简要描述如下:
- 超参数调优组件根据某种算法,选择一个超参数的组合,发送给模型训练组件
- 模型训练组件,根据给定超参数组合,设置到模型上,基于训练集开始启动训练过程
- 神经网络经过训练,得到一组模型参数,输出到模型评估组件,进行模型评估
- 模型评估组件根据训练得到的模型,评估损失和模型精度,并反馈给超参数调优组件
- 超参数调优组件判断当前的一个超参数组合是否是最优的,如果是则得到最优模型并终止,否则选择另一个超参数组合继续尝试
经过上面的超参数调优,我们可以看到超参数在模型优化过程中是非常重要的,调整超参数在模型训练流程之外进行选择,它要优先于模型参数被确定下来。而且,超参数调优是在尝试一个个超参数组合的过程中,得到了我们需要的模型参数。
在寻找到了最优的超参数和模型参数以后,接着就可以把我们的模型应用到某个基于模型的产品或应用中,对新的输入数据进行推理,得到实际业务应用场景需要的结果。
超参数调优,有如下两种使用方式:
- 手动超参数调优
- 自动超参数调优
当然,我们可以通过手动来选择超参数组合,并评估给出的超参数组合是否能得到最优的模型结果,但是手动处理太麻烦,而且很难更好地去管理超参数调优的流程,也容易出现人为的错误。尤其是在一个完整的应用/产品开发、应用的标准流程中,手动管理也会造成整体流程连续性的断裂,所以自动超参数调优(Automatic HPO)更适合现代的应用开发流程。
自动超参数调优,是指通过使用超参数调优算法来自动完成调优的过程。从工程角度来看,要想更好地实现自动化,我们只需要在使用超参数调优算法的基础上,将超参数调优相关的各个环节连接起来,实现可自动化执行。
超参数调优流程工程化
超参数调优过程自动化,我们可以通过构建 Library(库)和 Service/Platform(服务/平台)的方式,将超参数调优过程自动化过程封装起来提供工具,以简化用户使用超参数调优处理的工作量和难度,从而提高效率。
- Library 构建方式
使用 Library 的方式比较直接而且方便,只需要将超参数调优的算法及其处理逻辑封装成库文件,使用者在开发深度学习模型以及进行超参数调优时直接引用,整合在自己开发的深度学习模型训练调优的代码逻辑中,就能够方便地实现行模型训练及自动调优的整个流程。比如,Hyperopt、Ray Tune 是开源的 Python 自动超参数调优 Library,可以灵活使用。
- Service/Platform 构建方式
Service/Platform 的构建方式,需要从更多的方面去考虑,不仅要考虑实现使用超参数调优的用户的基本需求,还要实现 Service/Platform 与其它服务的交互、协作,也要把一些非功能性的需求如稳定性、扩展性等包括进去,对平台做架构设计、开发测试、发布上线。下面,我们从工程技术角度给出一个以构建 Service/Platform 方式的交互流程设计,以供参考,如下图所示:
在实际应用中,可以把上面的超参数调优流程的实现独立成公共服务,或者作为深度学习平台的一个模块以方便共享其他相关资源。
超参数调优算法
超参数调优的算法有很多,下面通过概要地描述一些算法,使我们能够了解这种算法的处理过程,以及为什么使用这种算法能够得到最优/更优超参数组合的结果。关于算法更加细节的内容,可以查找并参考对应的论文及其它相关资料。
- 网格搜索(Grid Search)
网格搜索,是选择每个超参数对应的取值的一个集合,然后对所有的取值进行组合,得到一个超参数组合的集合,接着再通过对这个集合中的每一个组合进行实验,即为模型配置好对应的超参数并进行训练评估,最后的得到最优的那个超参数组合。
可见,网格搜索这种方式并不高效,类似暴力搜索,如果每个超参数取值很多,那么得到的超参数组合会非常非常多,在大量的实验尝试中寻找最优的超参数组合,会浪费大量的计算资源,甚至在给定的受约束配额的资源量下根本无法找到最优的超参数组合。
- 随机搜索(Random Search)
随机搜索,通过每次随机从每个超参数的取值集合中取出一个值,构建一个超参数组合,然后在模型训练中使用这个超参数组合。随机搜索这种方式比较简单,能够有机会在资源配额受限的情况下,得到一个更加接近最优组合的超参数组合。
下面,我们把网格搜索和随机搜索放在一起对比,来理解这两种搜索方法的区别,如下图所示:
- 贝叶斯优化(Bayesian Optimization)
贝叶斯优化方法,在搜索最优超参数组合的过程中表现更加稳定,它能够通过更少的迭代轮次得到最优的超参数组合,因为它利用了前面实验的一些先验信息,比如试过的超参数组合值、模型训练的结果精度,通过统计推断的方法过滤掉了对无效超参数组合的盲目搜索尝试。
- TPE(Tree-structured Parzen Estimator)
TPE 算法提供了基于正向和反向梯度的搜索方式,是一种基于树结构的贝叶斯优化算法。对于每个超参数,TPE 为与最优目标值相关的超参数维护一个高斯混合模型 l(x),为其它的超参数维护另一个高斯混合模型 g(x),选择 l(x)/g(x) 最大化时对应的超参数作为下一组搜索的超参数组合,这样 TPE 算法能够自适应地调整参数搜索空间的大小,并且在尽可能少的迭代次数内找到最优的超参数组合结果。
- Hyperband
Hyperband 使用一种提前终止(Early Stopping)的策略来优化资源(Time、Dataset Subsampling、Feature Subsampling)分配,通过这种方式最大化能够评估的 Configuration 的数量。另外,Hyperband 也使用了随机搜索(Random Search)方法,通过调用 SuccessiveHalving 算法,随机得到一组超参数组合,这个过程查找的速度非常快。
另外,Hyperband 论文给出的性能数据是,使用 Hyperband 能够比贝叶斯优化算法快 5~30 倍。
- CMA-ES(Covariance Matrix Adaptation Evolution Strategy)
CMA-ES 是一种随机无梯度(Derivative-free)数值优化算法,它用来解决连续搜索空间的优化问题。CMA-ES 算法是一个随机算法,不需要计算目标函数的导数,计算效率很高。
CMA-ES 算法调整参数的思路:使用协方差矩阵 C,跟踪分布上得到的样本两两之间的依赖关系,调整参数使得产生好更优解的概率逐渐增大,即沿着更优的方向进行搜索的概率变大。
- BOHB(Bayesian Optimization and HyperBand)
BOHB 算法混合使用了 Hyperband 和贝叶斯优化两种算法,借助 Hyperband 算法的优势能够快速评估大量的超参数配置,借助贝叶斯优化算法的使用先验知识来引导对 Hyperband 得到的超参数配置进行再次评估过滤,得到的超参数配置更有机会使模型具备最优的性能。
- PBT(Population Based Training)
PBT 算法也使用了随机搜索(Random Search),PBT 在启动的时候类似使用并行搜索,使用随机搜索方法找到一组超参数组合以及一组模型初始参数,然后并行地对每个模型进行超参数优化。在算法运行过程中,周期性地异步检查这些训练中的模型的性能,如果发现某个模型性能低于预期,就使用其它性能表现好的模型替换这个模型(包括模型参数和对应的超参数),在这个模型训练结束之前继续使用表现好的模型的超参数组合,去探索可能会更优的超参数组合。使用 PBT 算法的超参数优化过程流程,如图所示(来自 PBT 论文):
可见,使用 PBT 算法的特点是超参数直接通过 Online 的方式进行探索和优化,这使得整个过程简单而且节省资源,速度也比较快,更有潜力找到更优的超参数。
超参数调优工具
一些超参数调优的工具,如下列表所示,可供参考:
- Hyperopt
- Goptuna
- Optuna
- BayesianOptimization
- Scikit-learn
- Scikit-Optimize
- Ray Tune
- Keras Tuner
- MOE(Metric Optimization Engine)
- GPyOpt
- Spearmint
- Fabolas(Bayesian Optimization on LArge data Sets)
- SigOpt
- HyperparameterHunter
总结
本文我们介绍了什么是超参数,并列出了在机器学习/深度学习中一些常见的超参数。找到更好的超参数组合,能够极大地提高模型的性能和表现,而且超参数调优本来就可以独立于模型本身来设计,这样可以开发出更多越来越来高效的超参数调优算法。
我们列出了一些常见超参数调优的算法,通过简单地介绍每一种算法的思想,能够更好地指导我们选择最合适的调优算法,并高效地进行超参数调优工作。通过讲述以 Library 和 Service/Platform 的两种方式构建超参数调优的工具,我们重点给出了基于 Service/Platform 方式构建自动化流程的参考设计。有了调优工具的辅助,能够更好地让我们专注于深度学习模型本身逻辑的开发,并使用调优工具更快地找到更合适的超参数组合。
最后,我们整理了一些常见的超参数调优工具列表,大多数都是基于 Python 编程语言,通过 Library 的构建方式实现的。这里就不再对这些工具进行展开描述,如果工作中有遇到需要超参数调优的场景,可以直接从列表中查找,并通过查找其他资料来详细评估每种工具的具体使用方法。
参考资源
- https://www.automl.org/blog_bohb/
- https://nanonets.com/blog/hyperparameter-optimization/
- https://www.kubeflow.org/docs/components/katib/experiment/#cmaes
- https://zhuanlan.zhihu.com/p/590823641
- https://blog.csdn.net/qq_43557907/article/details/129837714
- https://www.jianshu.com/p/e7f4ebd1a35a
- https://lilianweng.github.io/posts/2019-09-05-evolution-strategies/
- https://blog.csdn.net/deephub/article/details/135579926
- Designing Deep Learning Systems, CHI WANG/DONALD SZETO, 2023
本文基于署名-非商业性使用-相同方式共享 4.0许可协议发布,欢迎转载、使用、重新发布,但务必保留文章署名时延军(包含链接:http://shiyanjun.cn),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。