当前位置: 首页 > news >正文

模型优化调参利器贝叶斯优化bayesian-optimization实践

早在之前很多项目尤其是预测类型的项目中,就已经比较广泛地在实用贝叶斯优化库了,这是一个非常出色的纯python实现的项目,地址在这里,如下所示:

写这篇文章主要有两个目的,一方面是觉得这个工具库挺不错的值得学习使用;另一方面是这段时间陆陆续续在使用的过程中出现了很多莫名的错误,虽然一部分在官方的issues中已经得到了解决,但是还是有几个问题依旧是无法解决,所以就想着一方面找时间看下官方的介绍说明看看有没有合适的办法,另一方面就是作为一个开放讨论的平台,欢迎有同样问题的朋友交流沟通。

安装方式很简单:

$ pip install bayesian-optimization

贝叶斯优化通过构造函数的后验分布(高斯过程)来工作,该后验分布最好地描述了要优化的函数。随着观测值数量的增加,后验分布得到改善,算法更加确定参数空间中哪些区域值得探索,哪些区域不值得探索,如下图所示。

当您反复迭代时,该算法会根据其对目标函数的了解来平衡其探索和开发需求。在每个步骤中,将高斯过程拟合到已知样本(先前探索的点),并使用后验分布结合探索策略(例如UCB(置信上限)或EI(预期改进)),以确定应探索的下一个点(动图gif)。

此过程旨在最小化找到接近最佳组合的参数组合所需的步骤数。为此,该方法使用了一个代理优化问题(寻找捕获函数的最大值),尽管这仍然是一个困难的问题,但成本较低(在计算意义上),并且可以使用通用工具。因此,贝叶斯优化是最适合的情况下采样的功能进行优化是一个非常昂贵的努力。

官方项目中提供了基础使用教程和进阶使用教程还有一些对应的开发实例。

基础使用教程

这是一个基于贝叶斯推理和高斯过程的约束全局优化包,它试图在尽可能少的迭代中找到未知函数的最大值。该技术特别适用于高成本函数的优化,在这种情况下,勘探和开发之间的平衡非常重要。贝叶斯优化通过构造函数的后验分布(高斯过程)来工作,该后验分布最好地描述了要优化的函数。随着观测值数量的增加,后验分布得到改善,算法更加确定参数空间中哪些区域值得探索,哪些区域不值得探索,如下图所示。
当您反复迭代时,该算法会根据其对目标函数的了解来平衡其探索和开发需求。在每个步骤中,将高斯过程拟合到已知样本(先前探索的点),并使用后验分布结合探索策略(例如UCB(置信上限)或EI(预期改进)),以确定应探索的下一个点(参见下面的gif)。
此过程旨在最小化找到接近最佳组合的参数组合所需的步骤数。为此,该方法使用了一个代理优化问题(寻找捕获函数的最大值),尽管这仍然是一个困难的问题,但成本较低(在计算意义上),并且可以使用通用工具。因此,贝叶斯优化是最适合的情况下采样的功能进行优化是一个非常昂贵的努力。

1、指定优化函数

def black_box_function(x, y):"""Function with unknown internals we wish to maximize.This is just serving as an example, for all intents andpurposes think of the internals of this function, i.e.: the processwhich generates its output values, as unknown."""return -x ** 2 - (y - 1) ** 2 + 1

2、实践应用

from bayes_opt import BayesianOptimization
# Bounded region of parameter space
pbounds = {'x': (2, 4), 'y': (-3, 3)}
optimizer = BayesianOptimization(f=black_box_function,pbounds=pbounds,verbose=2, # verbose = 1 prints only when a maximum is observed, verbose = 0 is silentrandom_state=1,
)
optimizer.maximize(init_points=2,n_iter=3,
)
print(optimizer.max)
for i, res in enumerate(optimizer.res):print("Iteration {}: \n\t{}".format(i, res))
#修改参数边界
optimizer.set_bounds(new_bounds={"x": (-2, 3)})
optimizer.maximize(init_points=0,n_iter=5,
)

3、优化

optimizer.probe(params={"x": 0.5, "y": 0.7},lazy=True,
)
print(optimizer.space.keys)
optimizer.probe(params=[-0.3, 0.1],lazy=True,
)
optimizer.maximize(init_points=0, n_iter=0)

4、存储、加载、继续

#Saving progress
from bayes_opt.logger import JSONLogger
from bayes_opt.event import Eventslogger = JSONLogger(path="./logs.log")
optimizer.subscribe(Events.OPTIMIZATION_STEP, logger)
optimizer.maximize(init_points=2,n_iter=3,
)#Loading progress
from bayes_opt.util import load_logs
new_optimizer = BayesianOptimization(f=black_box_function,pbounds={"x": (-2, 2), "y": (-2, 2)},verbose=2,random_state=7,
)
print(len(new_optimizer.space))load_logs(new_optimizer, logs=["./logs.log"]);
print("New optimizer is now aware of {} points.".format(len(new_optimizer.space)))
new_optimizer.maximize(init_points=0,n_iter=10,
)

进阶使用教程

1.、Suggest-Evaluate-Register Paradigm

# Let's start by defining our function, bounds, and instantiating an optimization object.
def black_box_function(x, y):return -x ** 2 - (y - 1) ** 2 + 1optimizer = BayesianOptimization(f=None,pbounds={'x': (-2, 2), 'y': (-3, 3)},verbose=2,random_state=1,
)from bayes_opt import UtilityFunctionutility = UtilityFunction(kind="ucb", kappa=2.5, xi=0.0)next_point_to_probe = optimizer.suggest(utility)
print("Next point to probe is:", next_point_to_probe)target = black_box_function(**next_point_to_probe)
print("Found the target value to be:", target)optimizer.register(params=next_point_to_probe,target=target,
)#The maximize loop
for _ in range(5):next_point = optimizer.suggest(utility)target = black_box_function(**next_point)optimizer.register(params=next_point, target=target)print(target, next_point)
print(optimizer.max)

2、Dealing with discrete parameters

def func_with_discrete_params(x, y, d):# Simulate necessity of having d being discrete.assert type(d) == intreturn ((x + y + d) // (1 + d)) / (1 + (x + y) ** 2)
def function_to_be_optimized(x, y, w):d = int(w)return func_with_discrete_params(x, y, d)
optimizer = BayesianOptimization(f=function_to_be_optimized,pbounds={'x': (-10, 10), 'y': (-10, 10), 'w': (0, 5)},verbose=2,random_state=1,
)
optimizer.set_gp_params(alpha=1e-3)
optimizer.maximize()

3、Tuning the underlying Gaussian Process

optimizer = BayesianOptimization(f=black_box_function,pbounds={'x': (-2, 2), 'y': (-3, 3)},verbose=2,random_state=1,
)
optimizer.set_gp_params(alpha=1e-3, n_restarts_optimizer=5)
optimizer.maximize(init_points=1,n_iter=5
)from bayes_opt.event import DEFAULT_EVENTS, Events
optimizer = BayesianOptimization(f=black_box_function,pbounds={'x': (-2, 2), 'y': (-3, 3)},verbose=2,random_state=1,
)
class BasicObserver:def update(self, event, instance):"""Does whatever you want with the event and `BayesianOptimization` instance."""print("Event `{}` was observed".format(event))
my_observer = BasicObserver()optimizer.subscribe(event=Events.OPTIMIZATION_STEP,subscriber=my_observer,callback=None, # Will use the `update` method as callback
)def my_callback(event, instance):print("Go nuts here!")optimizer.subscribe(event=Events.OPTIMIZATION_START,subscriber="Any hashable object",callback=my_callback,
)
optimizer.maximize(init_points=1, n_iter=2)

进一步的详情可以自行了解官方教程即可。

简单的实践介绍就到这里,下面说两个还记得的报错问题。

1、StopIteration: Queue is empty error in optimizer.maximize()

关于这个问题,官方论坛和stackoverflow论坛里面都有很多讨论,也有给出一些对应的解决办法,但是都没有能解决我的问题。

2、"ValueError: array must not contain infs or NaNs" happens after self.suggest().

这个问题与上面问题往往是交替或者是同时出现的。

目前依旧在研究文档,不知道是不是自己哪里理解有误导致的,也欢迎有同样问题的朋友一起沟通交流。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java项目:基于SSM框架实现的校园快递代取管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • 14-38 剑和诗人12 - RAG+ 思维链 ⇒ 检索增强思维(RAT)
  • 星戈瑞CY7-Amine生物荧光成像
  • linux cpuspeed工具
  • 软件设计之Java入门视频(11)
  • Qt扫盲-QRect矩形描述类
  • Desktop docker 部署 WordPress
  • 智慧矿山:EasyCVR助力矿井视频多业务融合及视频转发服务建设
  • BDD 100K dataset 的标签数据结构(json文件)
  • ABAP中CONVERT_TO_LOCAL_CURRENCY 函数的使用方法
  • 安装elasticsearch
  • 动态黑窗口打印文字404页面源码
  • ELK优化之Elasticsearch
  • 如何摆脱反爬虫机制?
  • 【QT】常用控件|widget|QPushButton|RadioButton|核心属性
  • 2017 年终总结 —— 在路上
  • 2019.2.20 c++ 知识梳理
  • C# 免费离线人脸识别 2.0 Demo
  • conda常用的命令
  • exif信息对照
  • js ES6 求数组的交集,并集,还有差集
  • Nacos系列:Nacos的Java SDK使用
  • springMvc学习笔记(2)
  • Twitter赢在开放,三年创造奇迹
  • 构建工具 - 收藏集 - 掘金
  • 那些被忽略的 JavaScript 数组方法细节
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 一文看透浏览器架构
  • ​学习一下,什么是预包装食品?​
  • "无招胜有招"nbsp;史上最全的互…
  • #、%和$符号在OGNL表达式中经常出现
  • (C语言)字符分类函数
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (二)原生js案例之数码时钟计时
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (六)DockerCompose安装与配置
  • (七)理解angular中的module和injector,即依赖注入
  • (算法)Travel Information Center
  • (一)80c52学习之旅-起始篇
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .Net Core 微服务之Consul(二)-集群搭建
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET gRPC 和RESTful简单对比
  • .NET HttpWebRequest、WebClient、HttpClient
  • .Net Winform开发笔记(一)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET框架设计—常被忽视的C#设计技巧
  • .Net面试题4
  • @vue/cli脚手架
  • [ 第一章] JavaScript 简史
  • [] 与 [[]], -gt 与 > 的比较
  • []C/C++读取串口接收到的数据程序