兄弟们早上好,老胡之前在机器学习入门指南(2021版)一文中推荐了一本知名度比较低的书:《机器学习:软件工程方法与实现》
书中内容包含了工程基础、机器学习基础、特征原理与实现、模型原理及设计和调参方法,最后还讲解了模型监控和评估方式和方法。
调参是个玄学,各位炼丹师都有自己的独门绝技,但是基本功总是少不了的。对于还不太了解最基本,最常用的调参方法和工具的同学,可以看一下这篇文章。如有收获,欢迎三连。
以下内容摘编自《机器学习:软件工程方法与实现》,经出版方授权发布。
贝叶斯方法
网格搜索需要人为指定解的范围,随机搜索具有随机探索未知更好解的可能性,而贝叶斯方法能够启发式地探索更优解
贝叶斯优化就是一种寻找这类代价昂贵的目标函数极值的有效方法,
只需给到它一些观察点(超参,性能),贝叶斯优化方法能够基于观察的先验,指导超参采样,并权衡超参空间的探索(exploration)和开发(exploitation)。
在这个过程中使用了贝叶斯定理,故而称为贝叶斯优化
贝叶斯优化技术的实现是一种迭代式、序列化模式的优化框架,主要包括一个代理模型和一个决定下一个评估点的收益函数(Acquisition Function)。收益函数通过概率模型评估不同参数点的效能,选择最优的点继续迭代
要求代理模型和收益函数的评估比原始黑盒模型的训练和评估具有更高的效率,即训练、计算评估时间都较短,否则失去了“代理”的意义。
“决定下一个参数点”是一个权衡的过程:既要尝试那些之前没有尝试过区域的点(探索),也要选择当前预测较好的点(开发)
有很多收益函数可以选取,例如
PI(Probability of Improvement):概率提升法,最大化概率法,下次迭代时选取当前评估概率最大的点; EI(Expected Improvement)期望提升法,最大化期望,下次迭代时选取当前期望最大的点(兼顾了提升幅度); UCB(Upper Confidence Bound)/LCB(Lower Confidence Bound):置信上/下限法; ES(Entropy Search):基于信息论的方法等。
BayesianOptimization优化实例
开源包BayesianOptimization借用了sklearn.gaussian_process实现了基于高斯过程的贝叶斯优化。
“使用前安装:pip install bayesian-optimization
“GitHub地址: https://github.com/fmfn/BayesianOptimization。
优化示例
1)导入必要的包:
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier as RFC
from bayes_opt import BayesianOptimization
2)定义优化目标:
def rfc_cv_object(n_estimators, min_samples_split, max_features, data,
targets):
"""随机森林交叉验证
关注的超参空间:
n_estimators, min_samples_split, and max_features
目标:
最大化指标roc_auc,交叉验证的平均作为最终的模型效果
"""
estimator = RFC(n_estimators=n_estimators,
min_samples_split=min_samples_split,
max_features=max_features,
random_state=42)
cval = cross_val_score(estimator, data, targets, scoring='roc_auc', cv=4)
return cval.mean()
3)定义超参空间和优化器:
def optimize_rfc(data, targets):
def rfc_crossval(n_estimators, min_samples_split, max_features):
"""rfc_cv的二次封装,保证:
1.n_estimators和min_samples_split为整数
2.避免max_features在(0, 1)范围之外
"""
return rfc_cv_object(
n_estimators=int(n_estimators),
min_samples_split=int(min_samples_split),
max_features=max(min(max_features, 0.999), 1e-3),
data=data,
targets=targets,
)
optimizer = BayesianOptimization(
f=rfc_crossval,
# 超参空间
pbounds={
"n_estimators": (10, 250),
"min_samples_split": (2, 25),
"max_features": (0.1, 0.999),
},
random_state=42,
verbose=2)
# 2个初始化点和10轮优化,共12轮
optimizer.maximize(init_points=2, n_iter=10)
print("Final result:", optimizer.max)
return optimizer
4)调用优化:
ret = optimize_rfc(X_train, y_train)
输出如图所示。
所以本次优化得到最优的超参是:
{'max_features': 0.7865747545584155, 'min_samples_split': 2, 'n_estimators': 249}},其AUC为0.9867。
另外,ret.res中存储了每轮的调优记录,可用于超参分析。
BayesianOptimization主要接口介绍如下:
1)BayesianOptimization:贝叶斯优化对象类,重点有如下两个参数。
f:待优化的目标函数。 pbounds:超参空间的定义,需要限制超参的取值范围。该参数格式为字典型的元组格式,元组中指定了最小值和最大值。
2)主要的优化方法:maximize,该方法主要有如下3个参数。
n_iter:迭代次数,一般来说迭代次数越多,获得较好效果的可能就越大。 init_points:初始化随机探索的点,随机探索可以使探索空间多样化。 acq:收益函数,支持:'ucb'(缺省)、 'ei'、 'poi'。
3)set_bounds:支持随时更新超参范围。
4)probe方法支持用户自定义的空间探索,主要的参数如下所示。
params:指定探索的点。 lazy:赋值为True。
5)支持调优过程事件记录,存入到json文件中。涉及的方法为:
bayes_opt.logger import JSONLogger
推荐另外2个相关超参调优的开源包,它们相对封装更好一些,例如不用自行处理参数取整等操作。
1) scikit-optimize :也是基于Sklearn的贝叶斯优化的开源包,同时支持可视化高斯过程的接口等。
2) Hyperopt/Hyperopt-Sklearn :一个历史更悠久的开源优化包,当前基本已无更新,封装的功能较为完善。
限于篇幅,书中不再展开介绍,请读者自行参考学习。
部分开源调参项目简介
Ray-Tune
Tune是一款可扩展的,主要应用于深度学习、强化学习(也可以用于机器学习)的超参调优框架,其官网介绍的主要特点有 :
1)10行代码就能启动多节点的分布式的超参搜索;
2)支持任何机器学习框架,包括PyTorch、XGBoost、MXNet和Keras;
3)可原生的和多种优化库集成,例如HyperOpt、Bayesian Optimization和Facebook Ax;
4)可选用多种可扩展算法,如Population Based Training (PBT), Vizier’s Median Stopping Rule, HyperBand/ASHA;
5)可使用TensorBoard进行可视化。
Tune运行于Ray分布式计算框架上,而Ray是一个用于构建和运行分布式应用程序快速而简洁的框架,更进一步的了解,可参考 。
另外,Ray还衍生了一个不错的项目modin:Pandas的大数据版本或并行化多核版本,支持KB到TB级别的数据量,感兴趣的读者可以进一步研究
optuna
Optuna称为下一代超参调优框架(A Next-generation Hyperparameter Optimization Framework)。
GitHub可参考相关链接 ,也可参考相关论文 。
Optuna中介绍了如下内容。
1) 允许用户动态地构造参数搜索空间。
论文中提到:“到目前为止,所有的超参数优化框架都要求用户为每个模型静态地构造参数搜索空间,对于那些涉及巨大参数空间的不同类型的候选模型的大规模实验来说,
这些框架中的搜索空间是极难描述的,尤其是包含许多条件变量时问题更为明显。当用户对参数空间描述不当时,采用先进的优化方法是徒劳的”。
2) 能够高效地实现搜索和修剪策略:终止无希望试验的策略在许多文献中常被称为剪枝,也被称为自动提前停止。
许多现有的框架不具有高效的修剪策略。该框架提供了采样和修剪的良好设计。
3) 易于设置的、多用途的体系结构,可用于各种目的,从可扩展的分布式计算到由交互界面的轻量级实验。
4) 专门为机器学习而设计:它具有一个命令式的、按运行方式定义的用户API(define-by-run的软件设计原则)。
按该设计原则,使用Optuna编写的代码具有很高的模块化。
5) 支持通过后端数据库存储优化历史,便于分析和调优恢复。
从上述描述看,Optuna是一个非常优秀的优化软件框架,其软件设计思想值得学习。
本章小结
本章开篇讲述了模型调参问题的定义、超参数的理解和容易被大家忽视的“作弊的随机种子”——取随机最好的效果是没有意义的!
超参调整就是搜索模型结构的过程,就如调整树深,像是调整树的高度结构一样。
文中明确了调参的3个要素:目标函数、搜索域/超参空间、搜索算法。定义好了这3个要素就可以开始调参了
调参是先从复杂到简单还是从简单到复杂的方向的流程性问题,奥卡姆剃刀原则给出了提示。
由于手工调参的局限,书中介绍了自动调参涉及的元学习和代理模型方法,并提到了SmartML、Auto-sklearn等先进调参理念的开源实现
同时提到混合搜索:如贝叶斯+网格搜索、随机搜索+网格搜索。
1)网格搜索:固定备选的空间点;
2)随机搜索:随机选择的空间点;
3)贝叶斯:依分布选择的空间点。
调参实验中具有顺手的工具,调参想必会逐渐变成探索的乐趣。XGBoost自动调参工具实现了网格、随机和增量调参的模式,并在工程易用性上做了良好的设计
为了开阔读者的视野,12.6节介绍了笔者认为不错的开源项目:Ray-Tune、Optuna,以及适用于机器学习和深度学习的调参。
我们可以从中学到调参概念、先进的软件设计方法、调参的理念和调参工具的使用方法。从开源项目中学习,就是向全世界优秀的人学习!
推荐阅读
(点击标题可跳转阅读)
老铁,三连支持一下,好吗?↓↓↓