超参数优化
Bayesian Optimization使用Hyperopt进行参数调优
1. 前言
现在的机器学习和深度学习中,在模型结构确定的情况下,不同的超参数的选择对整个结果的好坏有着至关重要的影响。不少人还嬉称人工智能工程师,其实是“调参侠”。
1.1 超参数
在模型开始学习过程之前人为设置值的参数,而不是(像bias、weights)通过训练可得到的参数数据。
这些参数定义关于模型更高层次的概念(模型复杂性、学习能力等)。
比如说随机梯度下降算法中的学习速率/learning rate,出于计算复杂度和算法效率等,我们并不能从数据中直接学习一个比较不错的学习速度。但学习速率却又是十分重要的,较大的学习速率不易令模型收敛到较合适的较小值解,而较小的学习速率却又常常令模型的训练速度大大降低。对于像学习速率这样的超参数,我们通常需要在训练模型之前设定。因此,对于超参数众多的复杂模型,调超参技能显得很重要。
2. Grid Search
Grid Search用的是穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)
搜索整个超参数空间,在高维空间容易遇到维度灾难,不实用。
网格搜索是一种昂贵的方法。假设我们有n个超参数,每个超参数有两个值,那么配置总数就是2的N次方。因此,仅在少量配置上进行网格搜索是可行的。
网格搜索可以并行化,使得网格搜索在足够的计算能力下更加可行。
每次trial之间是相互独立的,不能利用先验知识选择下一组超参数。
3. Random Search
随机搜索是一种在巨大数据规模下执行一个耗时上无法接受的程序的优化方法。
数据规模大,精确的结果难以在一定时间计算出。
结果的些许的不精确能够被接受。
求取的结果是最优化(optimization)问题,有一个成本计算模型。
随机搜索的算法类型:
基本随机搜索
爬山搜索算法
模拟退火算法
遗传算法
4. GridSearch和RandomSearch的使用
这里给出一个GridSearch和RandomSearch的简单使用方式,方便同学们测试功能用。
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV
from sklearn.model_selection import train_test_split
# 加载数据集
iris = datasets.load_iris()
data = iris.data
label = iris.target
# 数据集分割
X_train,X_test,y_train,y_test = train_test_split(data,label,test_size=0.3,random_state=2)
knn_clf_orogin = KNeighborsClassifier()
# 搜索的超参数范围
param_grid ={
'weights':['distance'],
'n_neighbors':[i for i in range(1,11)],
'p':[i for i in range(1,6)]
}
grid_search = GridSearchCV(knn_clf,param_grid,n_jobs=-1,verbose=2)
grid_search.fit(X_train,y_train)
knn_clf1 = grid_search.best_estimator_
y_pre = knn_clf1.predict(X_test)
knn_clf1.score(X_test,y_pre)
# print('grid_search-度量记录:',grid_search.cv_results_)
print('grid_search-最佳度量值:',grid_search.best_score_)
print('grid_search-最佳参数:',grid_search.best_params_)
print('grid_search-最佳模型:',grid_search.best_estimator_)
random_search = RandomizedSearchCV(knn_clf_orogin,param_grid,n_jobs=-1,verbose=2)
random_search.fit(X_train,y_train)
knn_clf2 = random_search.best_estimator_
y_pre = knn_clf2.predict(X_test)
knn_clf2.score(X_test,y_pre)
# print('random_search-度量记录:',random_search.cv_results_)
print('random_search-最佳度量值:',random_search.best_score_)
print('random_search-最佳参数:',random_search.best_params_)
print('random_search-最佳模型:',random_search.best_estimator_)
虽然随机搜索得到的结果互相之间差异较大,但是实验证明随机搜索的确比网格搜索效果要好。
5. Bayesian Optimization
贝叶斯优化其实就是基于模型的超参数优化,根据已有的采样点预估函数,不断迭代获得最大值的一个算法。
5.1 Bayesian Optimization流程图
5.2 算法步骤
(f)是我们的的预估函数,也可以是一个黑盒的模型。
(X)是自定义的输入参数的范围
(S)是Acquisition Function(采集函数),这个函数的作用是通过最大化AF来选择下一个采样点。
(M)是先验函数(Prior Function,PF),可以通过(M)和(X)计算得出具体的模型具体函数表示。
模型步骤解析:
通过(INITSAMPLES(f,X))采集初始的样本(D={(x_1,y_1),(x_2,y_2)…(x_i,y_i)})
循环选参数(T)次:
通过(FITMODEL(M,D))计算出(p(y|x,D))的概率。
通过(S)的采集函数计算出(y)取值最大时的(x_i)。
判断(y_i)值是否满足要求。
如果不满足要求,继续计算整个过程。
5.3 优点
贝叶树优化和网格搜索相比,迭代次数少(节省时间),粒度可以到很小。
搜索方式自动化,不需要太多人工参与。
调参过程可以控制。
5.4 缺点
不容易找到全局最优解。
过程比较复杂。