贝叶斯优化BayesianOptimization
神经网络有很多超参数(学习率,正则等等)。如何寻找最好的超参数组合,穷举搜索 Grid Search 效率太低;随机搜索比穷举搜索好一点;目前比较好的解决方案是贝叶斯优化。1.贝叶斯优化的优点贝叶斯调参采用高斯过程,考虑之前的参数信息,不断地更新先验;网格搜索未考虑之前的参数信息;贝叶斯调参迭代次数少,速度快;网格搜索速度慢,参数多时易导致维度爆炸;贝叶斯调参针对非凸问题依然稳健;网格搜索针对非凸
神经网络有很多超参数(学习率,正则等等)。如何寻找最好的超参数组合,穷举搜索 Grid Search 效率太低;随机搜索比穷举搜索好一点;目前比较好的解决方案是贝叶斯优化。
1.贝叶斯优化的优点
- 贝叶斯调参采用高斯过程,考虑之前的参数信息,不断地更新先验;网格搜索未考虑之前的参数信息;
- 贝叶斯调参迭代次数少,速度快;网格搜索速度慢,参数多时易导致维度爆炸;
- 贝叶斯调参针对非凸问题依然稳健;网格搜索针对非凸问题易得到局部最优。
2. 贝叶斯初步优化
安装 相关包
pip install bayesian-optimization
使用随机森林作为模型进行参数优化
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from bayes_opt import BayesianOptimization
# 产生随机分类数据集,10个特征, 2个类别
x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)
# 不调参数的结果:
rf = RandomForestClassifier()
print(np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')))
# 0.965162
贝叶斯优化:先要定义一个目标函数。比如此时,函数输入为随机森林的所有参数,输出为模型交叉验证5次的AUC均值,作为我们的目标函数。
因为bayes_opt库只支持最大值,所以最后的输出如果是越小越好,那么需要在前面加上负号,以转为最大值。
def rf_cv(n_estimators, min_samples_split, max_features, max_depth):
val = cross_val_score(
RandomForestClassifier(
n_estimators=int(n_estimators),
min_samples_split=int(min_samples_split),
max_features=min(max_features, 0.999), # float
max_depth=int(max_depth),
random_state=2
),
x, y, scoring='roc_auc', cv=5
).mean()
return val
# 建立贝叶斯优化对象
# 第一个参数是我们的优化目标函数,第二个参数是我们所需要输入的超参数名称,以及其范围。超参数名称必须和目标函数的输入名称一一对应。
optimizer = BayesianOptimization(
f=rf_cv,
pbounds={
'n_estimators': (10, 250),
'min_samples_split': (2, 25),
'max_features': (0.1, 0.999),
'max_depth': (5, 15)
},
random_state=1234,
verbose=2
)
optimizer.maximize(n_iter=10)
print("Final result:", optimizer.max)
参数迭代结果如下:
3. 贝叶斯进阶优化(Explore)
上面bayes算法得到的参数并不一定最优,当然我们会遇到一种情况,就是我们已经知道有一组或是几组参数是非常好的了,我们想知道其附近有没有更好的。
这个操作相当于上文bayes优化中的Explore操作,而bayes_opt库给了我们实现此方法的函数:
下面添加了四组较优的超参数,让其在该参数基础上进行explore,可能会得到更好的结果。
optimizer.explore(
{
'n_estimators': [10, 100, 200],
'min_samples_split': [2, 10, 20],
'max_features': [0.1, 0.5, 0.9],
'max_depth': [5, 10, 15]
}
)
同时,还可以修改高斯过程的参数,高斯过程主要参数是核函数(kernel),还有其他参数可以参考sklearn.gaussianprocess:
gp_param = {
'kernel':None
}
optimizer.maximize(**gp_param)
如果kernel是None,1.0 * RBF(1.0)被用来当成默认的kernel。
但是从某种角度上来说,贝叶斯优化也是另外一种瞎猜。。。
更多推荐
所有评论(0)