本文旨在介绍当前被大家广为所知的超参自动优化方法,像网格搜索、随机搜索、贝叶斯优化和Hyperband,并附有相关的样例代码供大家学习。

一、网格搜索(Grid Search)

网格搜索是暴力搜索,在给定超参搜索空间内,尝试所有超参组合,最后搜索出最优的超参组合。sklearn已实现该方法,使用样例如下:

from sklearn import svm, datasets
from sklearn.model_selection import GridSearchCV
import pandas as pd# 导入数据
iris = datasets.load_iris()
# 定义超参搜索空间
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
# 初始化模型
svc = svm.SVC()
# 网格搜索
clf = GridSearchCV(estimator = svc,param_grid = parameters,scoring = 'accuracy',n_jobs = -1,cv = 5)
clf.fit(iris.data, iris.target)
返回:GridSearchCV(cv=5, estimator=SVC(), n_jobs=-1,param_grid={'C': [1, 10], 'kernel': ('linear', 'rbf')},scoring='accuracy')# 打印结果
print('详细结果:\n', pd.DataFrame.from_dict(clf.cv_results_))
print('最佳分类器:\n', clf.best_estimator_)
print('最佳分数:\n', clf.best_score_)
print('最佳参数:\n', clf.best_params_).
返回:
详细结果:mean_fit_time  std_fit_time  mean_score_time  std_score_time param_C  ... split3_test_score split4_test_score  mean_test_score  std_test_score  rank_test_score
0       0.000788      0.000394         0.000194        0.000389       1  ...          0.966667               1.0         0.980000        0.016330                1
1       0.000804      0.000402         0.000199        0.000399       1  ...          0.933333               1.0         0.966667        0.021082                4
2       0.000593      0.000484         0.000593        0.000484      10  ...          0.966667               1.0         0.973333        0.038873                3
3       0.000593      0.000484         0.000399        0.000489      10  ...          0.966667               1.0         0.980000        0.016330                1
[4 rows x 15 columns]
最佳分类器:SVC(C=1, kernel='linear')
最佳分数:
0.9800000000000001
最佳参数:{'C': 1, 'kernel': 'linear'}

sklearn.model_selection.GridSearchCV[1]的重要参数说明:

  • estimator: scikit-learn模型。

  • param_grid: 超参搜索空间,即超参数字典。

  • scoring: 在交叉验证中使用的评估策略。

  • n_jobs: 并行任务数,-1为使用所有CPU。

  • cv: 决定采用几折交叉验证。

二、随机搜索(Randomized Search)

随机搜索是在搜索空间中采样出超参组合,然后选出采样组合中最优的超参组合。随机搜索的好处如下图所示:

图1: 网格搜索和随机搜索的对比[2]

解释图1,如果目前我们要搜索两个参数,但参数A重要而另一个参数B并没有想象中重要,网格搜索9个参数组合(A, B),而由于模型更依赖于重要参数A,所以只有3个参数值是真正参与到最优参数的搜索工作中。反观随机搜索,随机采样9种超参组合,在重要参数A上会有9个参数值参与到搜索工作中,所以,在某些参数对模型影响较小时,使用随机搜索能让我们有更多的探索空间

同样地,sklearn实现了随机搜索[3],样例代码如下:

from sklearn import svm, datasets
from sklearn.model_selection import RandomizedSearchCV
import pandas as pd
from scipy.stats import uniform# 导入数据
iris = datasets.load_iris()
# 定义超参搜索空间
distributions = {'kernel':['linear', 'rbf'], 'C':uniform(loc=1, scale=9)}
# 初始化模型
svc = svm.SVC()
# 网格搜索
clf = RandomizedSearchCV(estimator = svc,param_distributions = distributions,n_iter = 4,scoring = 'accuracy',cv = 5,n_jobs = -1,random_state = 2021)
clf.fit(iris.data, iris.target)
返回:RandomizedSearchCV(cv=5, estimator=SVC(), n_iter=4, n_jobs=-1,param_distributions={'C': <scipy.stats._distn_infrastructure.rv_frozen object at 0x000001F372F9A190>,'kernel': ['linear', 'rbf']},random_state=2021, scoring='accuracy')# 打印结果
print('详细结果:\n', pd.DataFrame.from_dict(clf.cv_results_))
print('最佳分类器:\n', clf.best_estimator_)
print('最佳分数:\n', clf.best_score_)
print('最佳参数:\n', clf.best_params_)
返回:
详细结果:mean_fit_time  std_fit_time  mean_score_time  std_score_time  param_C  ... split3_test_score split4_test_score  mean_test_score  std_test_score  rank_test_score
0       0.000598      0.000489         0.000200        0.000400   6.4538  ...          0.966667               1.0         0.986667        0.016330                1
1       0.000997      0.000002         0.000000        0.000000  4.99782  ...          0.966667               1.0         0.980000        0.026667                3
2       0.000798      0.000399         0.000399        0.000488  3.81406  ...          0.966667               1.0         0.980000        0.016330                3
3       0.000598      0.000488         0.000200        0.000399  5.36286  ...          0.966667               1.0         0.986667        0.016330                1
[4 rows x 15 columns]
最佳分类器:SVC(C=6.453804509266643)
最佳分数:
0.9866666666666667
最佳参数:{'C': 6.453804509266643, 'kernel': 'rbf'}

相比于网格搜索,sklearn随机搜索中主要改变的参数是param_distributions,负责提供超参值分布范围。

三、贝叶斯优化(Bayesian Optimization)

我写本文的目的主要是冲着贝叶斯优化来的,一直有所耳闻却未深入了解,所以我就来查漏补缺了。以下内容主要基于Duane Rich在《How does Bayesian optimization work?》[4]的回答。

调优的目的是要找到一组最优的超参组合,能使目标函数f达到全局最小值。

举个例子,若学习率设置过大,模型可能会在代价函数的全局最优点附近不断来回震荡,甚至跳出全局最优点,而设置过小,又可能会陷入局部最优,因此调学习率这一参数,是为了让模型能收敛到代价函数的全局最小值。可是在机器学习中,目标函数  常是被称作expensive blackbox function,计算开销大且不一定为凸函数。为此,贝叶斯优化出现了,它特别适合针对expensive blackbox function找到全局最优。

假设我们的真实的目标函数  长下图这样:

图2: 目标函数f(x)[4]

注意: 目标函数  的  是指超参数,我们希望找到最优的超参  去得到最小的  。为什么用虚线表示  呢?因为它是黑箱函数(blackbox function)。

现在,我们怎么找到  全局最小值点呢?我们能不能先在  上随机采样10个点,然后取它们的最小值呢?

图3: 随机采样10个点的目标函数f(x)[4]

图3里确实有个点挺靠近全局最优点的,那是不是在它附近再采样几个点,不断重复就行了?没那么简单,万一起始采样点在局部最小值附近,那这种方法会很容易陷入局部最优。关于“如何找到下一个合适的点”这个问题,我们先放一放,因为我们漏掉一个重点:每次尝试一种超参值  ,计算  的代价是昂贵的,为了减轻开销,贝叶斯优化采用了代理模型(surrogate model),代理模型可以被看作是一个简单模型去拟合原本复杂且不好理解的模型,简单来说,就是  计算太昂贵了,我们就用代理模型去代替它。

贝叶斯优化使用了高斯过程(gasussian processes, GP)去构建代理模型,高斯过程的细节这里暂时不讲,有兴趣的小伙伴可以自行查阅资料了解。基于给定的输入和输出,GP会推断出一个模型(这里为代理模型)。假设我们从昂贵的  采样了4个点,然后我们把这4个点交给GP,它会返回一个代理模型,如下图所示:

图4: 目标函数f(x)和代理模型[4]

绿色实线就是GP猜的代理模型,绿色条带是输出分布的标准差(即为Uncertainty)。我们有了代理模型,后续我们去找下一个合适的超参值,就能带入到计算开销相对较小的代理模型中,评估给定超参值的情况。

现在,我们来思考回之前提到的问题:"如何找到下一个合适的点?",这个问题本质是在问:“哪里有全局最小的点?”,为了解决这个问题,我们要关注两个地方:

(1) 已开发区域: 在绿色实线上最低的超参点。因为很可能它附近存在全局最优点。

(2) 未探索区域: 绿色实线上还未被探索的区域。比如图4,相比于0.15-0.25区间,0.65-0.75区间更具有探索价值(即该区间Uncertainty更大)。探索该区域有利于减少我们猜测的方差。

为了实现以上探索和开发的平衡(exploration-exploitation trade-off),贝叶斯优化使用了采集函数(acquisition function),它能平衡好全局最小值的探索和开发。采集函数有很多选择,其中最常见的是expectated of improvement(EI)[5],我们先看一个utility function:

是目前观察到的最小值,  是超参值,我们希望上述utility function输出越大越好(即找到的  能获得比当前最小值还小),基于  ,EI采集函数如下所示:

具有最高的EI的超参值  会被选择。EI有两部分:

(1) 减少均值函数  ,提高EI。

(2) 增加方差  ,提高EI。

所以EI的提高是建立在均值和方差的trade-off,也是exploration和exploitation的trade-off。

图5: 采集函数A(x)

图5我们可以看到,  时EI最大,所以我们下一个超参值  应该选1。

讲到这里,我们来看下完整的贝叶斯优化步骤是怎样的:

图6: 贝叶斯优化-SMBO

SMBO是简洁版的贝叶斯优化,伪代码如图6所示,具体如下:

(1) 准备输入: expensive blackbox function   ,超参搜索空间  ,采样数据集  (超参组合  ,对应  输出值),采集函数  和用数据集  拟合的代理模型M。

(2) 基于  和  ,采样得到数据集  。

(3) 循环选  次参数:

  1. 用当前数据集  拟合代理模型  ,实现模型更新。

  2. 选择使采集函数  最大的超参组合  。

  3. 将  带入  中,得到输出值  。(注意这里  的计算开销大)

  4. 将新的  加入到现有数据集  中。

目前,Hyperopt[6]开源代码库已实现基于TPE(Tree-structured Parzen Estimator Approach)的贝叶斯优化,图6我们能看到GP构建的概率模型是  ,而TPE是  和  ,关于TPE和GP的对比讨论,建议阅读论文[7]。TPE样例代码如下:

from sklearn import svm, datasets
from sklearn.model_selection import cross_val_score
from hyperopt import hp, fmin, tpe, space_eval
import pandas as pd# 导入数据
iris = datasets.load_iris()# step1: 定义目标函数
def objective(params):# 初始化模型并交叉验证svc = svm.SVC(**params)cv_scores = cross_val_score(svc, iris.data, iris.target, cv=5)# 返回loss = 1 - accuracy (loss必须被最小化)loss = 1 - cv_scores.mean()return loss# step2: 定义超参搜索空间
space = {'kernel':hp.choice('kernel', ['linear', 'rbf']),'C':hp.uniform('C', 1, 10)}# step3: 在给定超参搜索空间下,最小化目标函数
best = fmin(objective, space, algo=tpe.suggest, max_evals=100)
返回: best_loss: 0.013333333333333308(即accuracy为0.9866666666666667)# step4: 打印结果
print(best)
返回:{'C': 6.136181888987526, 'kernel': 1}(PS:kernel为0-based index,这里1指rbf)

四、Hyperband

除了格子搜索、随机搜索和贝叶斯优化,还有其它自动调参方式。例如Hyperband optimization[8],Hyperband本质上是随机搜索的一种变种,它使用早停策略和Sccessive Halving算法去分配资源,结果是Hyperband能评估更多的超参组合,同时在给定的资源预算下,比贝叶斯方法收敛更快,下图展示了Hyperband的早停和资源分配:

图7: Hyperband的超参选择和评估

在Hyperband之后,还出现了BOHB,它混合了贝叶斯优化和Hyperband。Hyperband和BOHB的开源代码可参考HpBandSter库[9],这里不展开细讲。

五、总结

上面我们用Iris鸢尾花数据集试了不同的超参自动调优方法,发现贝叶斯优化和随机搜索都比格子搜索好。从一些论文反映,贝叶斯优化是更香的,但是贝叶斯优化好像在实践中用的不是那么多,网上也有很多分享者,像Nagesh Singh Chauhan,说的那样:

As a general rule of thumb, any time you want to optimize tuning hyperparameters, think Grid Search and Randomized Search! [10]

Hyperparameter Optimization for Machine Learning Models - Nagesh Singh Chauhan

为什么呢?我想原因是贝叶斯的开销太大了,前面有提到,在每次循环选超参值的时候,贝叶斯优化都需要将  带入昂贵的目标函数  中,去得到输出值y,当目标函数特别复杂时,这种情况的评估开销是很大的,更何况随着搜索空间和搜索次数的变大,计算会越发昂贵。在知乎《为什么基于贝叶斯优化的自动调参没有大范围使用?》[11]中,很多知乎主也给出了很认真的回复,建议有兴趣的朋友移步阅读。

写这篇文章的过程中,我主要学到了2点,一是随机搜索在某些时候会比格子搜索好,二是了解贝叶斯优化的机理。这里,谈谈我比赛和个人实践中的体会,我很少会花过多时间在超参的调优上,因为它带来的收益是有限的,很多时候比起压榨模型来说,思考和挖掘数据特征能带来更多的收益,所以我想这也是为什么上面说:在任何想要调优超参时,先用格子搜索或随机搜索吧。总之,希望这篇文章对大家有帮助,我们下期再见~

参考资料

[1]  sklearn.model_selection.GridSearchCV, 官方文档: https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV

[2] Bergstra, J., & Bengio, Y. (2012). Random search for hyper-parameter optimization. Journal of machine learning research, 13(2).

[3] sklearn.model_selection.RandomizedSearchCV, 官方文档: https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html#sklearn.model_selection.RandomizedSearchCV

[4] Quora: How does Bayesian optimization work? - Duane Rich, 回答: https://www.quora.com/How-does-Bayesian-optimization-work

[5] Bayesian Optimization (2018). - Cse.wustl.edu. 课程Note: https://www.cse.wustl.edu/~garnett/cse515t/spring_2015/files/lecture_notes/12.pdf

[6] Hyperopt: Distributed Hyperparameter Optimization, 代码: https://github.com/hyperopt/hyperopt#getting-started

[7] Bergstra, J., Bardenet, R., Bengio, Y., & Kégl, B. (2011, December). Algorithms for hyper-parameter optimization. In 25th annual conference on neural information processing systems (NIPS 2011) (Vol. 24). Neural Information Processing Systems Foundation.

[8] Li, L., Jamieson, K., DeSalvo, G., Rostamizadeh, A., & Talwalkar, A. (2017). Hyperband: A novel bandit-based approach to hyperparameter optimization. The Journal of Machine Learning Research, 18(1), 6765-6816.

[9] HpBandSter开源代码库, 代码: https://github.com/automl/HpBandSte

[10] Hyperparameter Optimization for Machine Learning Models - Nagesh Singh Chauhan, 文章: [https://www.kdnuggets.com/2020/05/hyperparameter-optimization-machine-learning-models.html

[11] 为什么基于贝叶斯优化的自动调参没有大范围使用?- 知乎, 问答: https://www.zhihu.com/question/33711002

干货学习,三连

机器学习调参自动优化方法相关推荐

  1. Lesson 6.5Lesson 6.6.1Lesson 6.6.2 机器学习调参基础理论与网格搜索多分类评估指标的macro与weighted过程GridSearchCV的进阶使用方法

    Lesson 6.5 机器学习调参基础理论与网格搜索 在上一小节执行完手动调参之后,接下来我们重点讨论关于机器学习调参的理论基础,并且介绍sklearn中调参的核心工具--GridSearchCV. ...

  2. 机器学习:贝叶斯和优化方法_Facebook使用贝叶斯优化在机器学习模型中进行更好的实验

    机器学习:贝叶斯和优化方法 I recently started a new newsletter focus on AI education. TheSequence is a no-BS( mea ...

  3. 遗传算法优化rbf神经网络自校正控制的初值_【技术帖】轻量化设计中的NVH性能自动优化方法...

    摘 要:噪声.振动与声振粗糙度 (Noise,Vibration and Harshness,NVH)性能的自动优化是实现多学科联合优化的基础条件.以白车身模型的零件厚度作为设计变量,以针对动刚度性能 ...

  4. 机器学习调参神器——网格搜索方法

    网格搜索方法主要用于模型调参,也就是帮助我们找到一组最合适的模型设置参数,使得模型的预测达到更好的效果,这组参数于模型训练过程中学习到的参数不同,它是需要在训练前预设好的,我们称其为超参数. 超参数的 ...

  5. 机器学习 | 调参 Part1

    调参系列1 1 什么叫调参? 2 为什么要调参 3 调参方法有哪些? 3.1 网格搜索 3.1.1 原理 3.1.2 Python实现 3.2 随机搜索 3.2.1 原理 3.2.2 Python实现 ...

  6. python模型调参三种方法

    1.机器学习常用三种调参方法:网格搜索.随机搜索和贝叶斯调参 2.网格搜索是遍历式搜索方法,效率较低,资源消耗多 3.网格搜索和随机搜索都没有考虑前面搜索的先验知识 4.贝叶斯调参的原理是贝叶斯优化, ...

  7. 机器学习中常用的优化方法

    写在前面 在看斯坦福的次cs231n课程,里面提到一些机器学习的基础知识,比如损失函数,优化算法,正则化形式等等.然后有一些知识也都记不起来了,索性就在博客上再回顾一遍顺便记录下来日后方便查阅.今天就 ...

  8. 机器学习案例系列教程——优化方法总结(梯度下降法、牛顿法、拟牛顿法、共轭梯度法等)

    梯度下降法 梯度下降法是最早最简单,也是最为常用的最优化方法.梯度下降法实现简单,当目标函数是凸函数时,梯度下降法的解是全局解.一般情况下,其解不保证是全局最优解,梯度下降法的速度也未必是最快的.梯度 ...

  9. 基于Python的随机森林(RF)回归与多种模型超参数自动优化方法

      本文详细介绍基于Python的随机森林(Random Forest)回归算法代码与模型超参数(包括决策树个数与最大深度.最小分离样本数.最小叶子节点样本数.最大分离特征数等等)自动优化代码.    ...

最新文章

  1. 微软软件保护平台 白皮书.pdf
  2. 一个比较笨的全文搜索的例子(分析结构用)-模糊查找
  3. Spark Mllib里的如何对单个数据集用斯皮尔曼计算相关系数
  4. springboot thymeleaf 引入jquery_超详细实战:SpringBoot高级之autoconfigure自动化配置
  5. java 删除.svn_使用JAVA的程序删除项目中的SVN目录
  6. java反射基础_Java反射基础 - havie的笔记 - 记笔记 - 私塾在线 - 只做精品视频课程服务...
  7. java云购_ycyg: 源创元购,一元云购java springmvc版本 云购商城 开源一元云购 开源java商城...
  8. JAVA 高频算法面试题汇总
  9. RS232和TTL电平
  10. python基本类型关键字_python中的关键字---1(基础数据类)
  11. 质因数分解,(结果简化版)
  12. WOS(五)——字段标识
  13. 软件构造之抽象相关知识总结
  14. 30_ElasticSearch IK分词器配置文件 以及自定义词库
  15. 学习笔记(01):国内第1套_Spring4 视频教程-佟刚_Spring_HelloWorld
  16. 3DMax”——新手小白入门篇
  17. 手工彻底清除各种顽固性 Trojan Horse ***的方法
  18. 【转】通俗易懂!白话朴素贝叶斯
  19. hdu1878欧拉回路(DFS+欧拉回路)
  20. 2011年计算机组成原理试卷答案,计算机组成原理试卷含答案

热门文章

  1. HTML5 3D旋转图片相册
  2. EasyPusher实现Android手机屏幕桌面直播,实时推送操作画面,用于手游直播等应用
  3. Sublime Text 3 (含:配置 C# 编译环境)
  4. WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程
  5. PL SQL笔记(三)
  6. C 语言中的 strtok 调用小技巧
  7. 6-6.用HLSL定义点光源
  8. 中国电子学会图形化四级编程题:成语接龙
  9. 华为发布《AR洞察与应用实践白皮书》,提出用5G点燃AR,用AR照亮5G
  10. 自动化神经网络理论进展缓慢,AutoML算法的边界到底在哪?