Scalable Global Optimization via Local Bayesian Optimization

  • 概述
  • 一、 GPR应用的简单例子
  • 二、TuRBO的文章介绍
    • 2.1 局部信赖域BO
  • 2.2 全局信赖域BO(TuRBO)
  • 三、TuRBO代码分析
  • 参考资料

概述

回顾一下高斯过程:

有一个数据集D={(xi,yi)}i=1n\mathcal D=\{(x_i,y_i)\}_{i=1}^nD={(xi​,yi​)}i=1n​,xix_ixi​是第iii个data point,yiy_iyi​是第iii个label:

GP Model:f(x)∼N(μn(x),σn(x))Likelihood:y(x)=f(x)+ϵ,ϵ∼N(0,σ2I)\text{GP Model}:f(x)\sim \mathcal N(\mu_n(x),\sigma_n(x))\\ \text{Likelihood}:y(x)=f(x)+\epsilon, \epsilon\sim \mathcal N(0,\sigma^2I)GP Model:f(x)∼N(μn​(x),σn​(x))Likelihood:y(x)=f(x)+ϵ,ϵ∼N(0,σ2I)

  1. 需要在Model中指定Kernel的类型即σn(x)\sigma_n(x)σn​(x)和初始化超参
  2. 需要在Likelihood中指定噪声的类型以及初始化的超参数
  3. 训练的目的是学习适应数据Kernel以及噪声的超参
  4. 训练的目标(或损失)是Marginal LogLikelihood (MLL)

一、 GPR应用的简单例子

假设labels的真实生成过程如下:
y(x)=sin(2πx)+ϵ,ϵ∼N(0,0.04)y(x)=sin(2\pi x)+\epsilon,\epsilon\sim \mathcal N(0, 0.04)y(x)=sin(2πx)+ϵ,ϵ∼N(0,0.04)

其中0.040.040.04不知道,sin(2πx)sin(2\pi x)sin(2πx)的形式也不知道。

  1. Kenel的选择。下面代码取RBF的kernel以及加一个outscale,公式如下:
    k(x1,x2)=αexp⁡(−12(x1−x2)⊤(x1−x2)l2)k(x_1,x_2)=\alpha\exp\left(-\frac{1}{2}\frac{(x_1-x_2)^\top(x_1-x_2)}{l^2}\right) k(x1​,x2​)=αexp(−21​l2(x1​−x2​)⊤(x1​−x2​)​)

    其中α\alphaα是outputscale,lll是lengthscale,是Kernel的超参数

  2. 噪声的选择。Likelihood选择其噪声的形式正态分布,方差σ\sigmaσ是一个需要学习的超参数,公式如下:
    ϵ∼N(0,σ)\epsilon \sim \mathcal N(0,\sigma)ϵ∼N(0,σ)

  3. 计算MLL。给定数据X,yX,yX,y,拟合的GP模型f∼GP(μ,K)f\sim \mathcal{GP}(\mu,K)f∼GP(μ,K),公式如下:
    pf(y∣x)=∫p(y∣f(x)p(f(x)∣x)dfp_f(y|x)=\int p(y|f(x)p(f(x)|x)dfpf​(y∣x)=∫p(y∣f(x)p(f(x)∣x)df

下面给出一个可以直接跑的例子(请安装gpytorch和torch):

import torch
import gpytorch
import math
from matplotlib import pyplot as plt# 准备数据 x
train_x = torch.linspace(0, 1, 100)
# 准备标签 y
train_y = torch.sin(train_x * (2 * math.pi)) + torch.randn(train_x.size()) * math.sqrt(0.04)
# 设定训练次数
training_iter = 50# 选择mean和covariance function即kernelclass ExactGPModel(gpytorch.models.ExactGP):def __init__(self, train_x, train_y, likelihood):super(ExactGPModel, self).__init__(train_x, train_y, likelihood)self.mean_module = gpytorch.means.ConstantMean()self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel())def forward(self, x):mean_x = self.mean_module(x)covar_x = self.covar_module(x)return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)# 构建一个关于噪声的模型计算likelihood以及要学习的GP模型
likelihood = gpytorch.likelihoods.GaussianLikelihood()
model = ExactGPModel(train_x, train_y, likelihood)model.train()
likelihood.train()# 优化器
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)# 计算损失
mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)for i in range(training_iter):optimizer.zero_grad()output = model(train_x)loss = -mll(output, train_y)loss.backward()print('Iter %d/%d - Loss: %.3f  outputscale:%.3f lengthscale: %.3f   noise: %.3f' % (i + 1, training_iter, loss.item(),model.covar_module.outputscale.item(),model.covar_module.base_kernel.lengthscale.item(),model.likelihood.noise.item()))optimizer.step()model.eval()
likelihood.eval()# 构建测试数据 test_x
with torch.no_grad(), gpytorch.settings.fast_pred_var():test_x = torch.linspace(0, 1, 51)observed_pred = likelihood(model(test_x))# 画图
with torch.no_grad():f, ax = plt.subplots(1, 1, figsize=(16, 9))lower, upper = observed_pred.confidence_region()ax.plot(train_x.numpy(), train_y.numpy(), 'k*')ax.plot(test_x.numpy(), observed_pred.mean.numpy(), 'b')ax.fill_between(test_x.numpy(), lower.numpy(), upper.numpy(), alpha=0.5)ax.set_ylim([-3, 3])ax.legend(['Observed Data', 'Mean', 'Confidence'])

print的输出:

Iter 1/50 - Loss: 0.934 outputscale:0.693 lengthscale: 0.693   noise: 0.693
Iter 2/50 - Loss: 0.903 outputscale:0.744 lengthscale: 0.644   noise: 0.644
Iter 3/50 - Loss: 0.869 outputscale:0.798 lengthscale: 0.598   noise: 0.598
Iter 4/50 - Loss: 0.831 outputscale:0.855 lengthscale: 0.555   noise: 0.554
Iter 5/50 - Loss: 0.789 outputscale:0.913 lengthscale: 0.514   noise: 0.513
Iter 6/50 - Loss: 0.742 outputscale:0.974 lengthscale: 0.475   noise: 0.474
Iter 7/50 - Loss: 0.693 outputscale:1.038 lengthscale: 0.438   noise: 0.437
Iter 8/50 - Loss: 0.643 outputscale:1.105 lengthscale: 0.404   noise: 0.402
Iter 9/50 - Loss: 0.595 outputscale:1.173 lengthscale: 0.371   noise: 0.370
Iter 10/50 - Loss: 0.551 outputscale:1.243 lengthscale: 0.341   noise: 0.339
Iter 11/50 - Loss: 0.512 outputscale:1.309 lengthscale: 0.315   noise: 0.311
Iter 12/50 - Loss: 0.475 outputscale:1.368 lengthscale: 0.291   noise: 0.284
Iter 13/50 - Loss: 0.441 outputscale:1.418 lengthscale: 0.272   noise: 0.260
Iter 14/50 - Loss: 0.408 outputscale:1.455 lengthscale: 0.256   noise: 0.237
Iter 15/50 - Loss: 0.375 outputscale:1.481 lengthscale: 0.243   noise: 0.216
Iter 16/50 - Loss: 0.343 outputscale:1.494 lengthscale: 0.234   noise: 0.197
Iter 17/50 - Loss: 0.311 outputscale:1.496 lengthscale: 0.226   noise: 0.179
Iter 18/50 - Loss: 0.280 outputscale:1.488 lengthscale: 0.221   noise: 0.163
Iter 19/50 - Loss: 0.249 outputscale:1.471 lengthscale: 0.218   noise: 0.148
Iter 20/50 - Loss: 0.219 outputscale:1.447 lengthscale: 0.216   noise: 0.135
Iter 21/50 - Loss: 0.189 outputscale:1.415 lengthscale: 0.216   noise: 0.123
Iter 22/50 - Loss: 0.161 outputscale:1.379 lengthscale: 0.218   noise: 0.112
Iter 23/50 - Loss: 0.134 outputscale:1.337 lengthscale: 0.221   noise: 0.102
Iter 24/50 - Loss: 0.109 outputscale:1.293 lengthscale: 0.224   noise: 0.093
Iter 25/50 - Loss: 0.087 outputscale:1.245 lengthscale: 0.229   noise: 0.084
Iter 26/50 - Loss: 0.066 outputscale:1.197 lengthscale: 0.235   noise: 0.077
Iter 27/50 - Loss: 0.048 outputscale:1.147 lengthscale: 0.242   noise: 0.071
Iter 28/50 - Loss: 0.033 outputscale:1.097 lengthscale: 0.249   noise: 0.065
Iter 29/50 - Loss: 0.021 outputscale:1.048 lengthscale: 0.256   noise: 0.060
Iter 30/50 - Loss: 0.012 outputscale:1.000 lengthscale: 0.264   noise: 0.055
Iter 31/50 - Loss: 0.006 outputscale:0.955 lengthscale: 0.271   noise: 0.051
Iter 32/50 - Loss: 0.003 outputscale:0.912 lengthscale: 0.279   noise: 0.048
Iter 33/50 - Loss: 0.003 outputscale:0.873 lengthscale: 0.286   noise: 0.045
Iter 34/50 - Loss: 0.004 outputscale:0.839 lengthscale: 0.292   noise: 0.042
Iter 35/50 - Loss: 0.008 outputscale:0.809 lengthscale: 0.297   noise: 0.040
Iter 36/50 - Loss: 0.012 outputscale:0.785 lengthscale: 0.300   noise: 0.038
Iter 37/50 - Loss: 0.016 outputscale:0.767 lengthscale: 0.301   noise: 0.037
Iter 38/50 - Loss: 0.020 outputscale:0.755 lengthscale: 0.301   noise: 0.036
Iter 39/50 - Loss: 0.023 outputscale:0.748 lengthscale: 0.299   noise: 0.035
Iter 40/50 - Loss: 0.024 outputscale:0.746 lengthscale: 0.296   noise: 0.034
Iter 41/50 - Loss: 0.025 outputscale:0.747 lengthscale: 0.291   noise: 0.034
Iter 42/50 - Loss: 0.024 outputscale:0.751 lengthscale: 0.286   noise: 0.034
Iter 43/50 - Loss: 0.023 outputscale:0.757 lengthscale: 0.280   noise: 0.034
Iter 44/50 - Loss: 0.021 outputscale:0.764 lengthscale: 0.274   noise: 0.035
Iter 45/50 - Loss: 0.018 outputscale:0.771 lengthscale: 0.268   noise: 0.035
Iter 46/50 - Loss: 0.016 outputscale:0.777 lengthscale: 0.263   noise: 0.036
Iter 47/50 - Loss: 0.013 outputscale:0.782 lengthscale: 0.258   noise: 0.037
Iter 48/50 - Loss: 0.010 outputscale:0.785 lengthscale: 0.253   noise: 0.038
Iter 49/50 - Loss: 0.008 outputscale:0.786 lengthscale: 0.249   noise: 0.039
Iter 50/50 - Loss: 0.006 outputscale:0.785 lengthscale: 0.245   noise: 0.040

上述代码画出来的图如下:

为什么GP model要学习?
就是为了拟合与数据相关的超参数。

二、TuRBO的文章介绍

在上一篇关于BO的文章贝叶斯优化中提到,BO最常用的关于统计量建模用的是GP,然后利用acquisition function选择下一个候选点。而TuRBO的关键就是利用Trust Region Method来设计了一个strategy结合Thomson Sampling来选择下一个候选点。

为了阐述这个关键点,下面主要分为一个局部信赖域模型local trust region BO 和 global trust region BO来描述TuRBO

2.1 局部信赖域BO

出发点:
想要GP完全拟合好一个高维的x∈Rdx\in \mathcal R^dx∈Rd可能比较困难,毕竟GP正态分布的分布结构不一定适合数据那一维度对应的空间,抑或是数据维度之间值变化太大了,GP捕捉拟合能力有限,术语即GP模型容量有限。因此,先拟合一个数据子域的模型总行吧,那这个子域怎么表示?怎样才算拟合好呢?

假设x=(x1,...,xd)x=(x_1,...,x_d)x=(x1​,...,xd​),Trust Region来表示子域,用Lmin,LmaxL_{min},L_{max}Lmin​,Lmax​代表最小的子域长度和最大的子域长度。所以对于点x(0)x^{(0)}x(0),其最大子域为x(0)±Lmaxx^{(0)}\pm L_{max}x(0)±Lmax​。所以对一个局部信赖域BO关键的地方在于怎么迭代各维度的长度,从而GP对该子域拟合得不错,即可信赖的子域(信赖域)!

寻找“恰当”子域策略为:

  1. 初始化子域的基本长度L←LinitL\leftarrow L_{init}L←Linit​
  2. 经过τsucc\tau_{succ}τsucc​次“成功”,扩张子域长度L←max⁡{Lmax,2L}L\leftarrow \max\{L_{max}, 2L\}L←max{Lmax​,2L}
  3. 经过τfail\tau_{fail}τfail​次“失败”,收缩子域长度L←min⁡{Lmin,L/2}L\leftarrow \min{\{L_{min},L/2\}}L←min{Lmin​,L/2}

采集函数的具体流程:

  1. 同样从已有或初始的数据集D0={(xi,yi)}i=1N\mathcal D_0=\{(x_i,y_i)\}_{i=1}^ND0​={(xi​,yi​)}i=1N​中选出最大值y∗∈D0y^*\in \mathcal D_0y∗∈D0​及其对应的x∗∈Rdx^*\in \mathcal R^dx∗∈Rd
  2. 在这个x∗=(x1∗,x2∗,...,xd∗)x^*=(x_1^*,x_2^*,...,x_d^*)x∗=(x1∗​,x2∗​,...,xd∗​)里确定一个Trust Region,假设基本长度值为L←LinitL\leftarrow L_{init}L←Linit​,各个维度设定一个length scale λi\lambda_iλi​,通过rescaling来确定每一个维度的具体长度:Li=λiL(∏j=1dλj)1dL_i=\frac{\lambda_iL}{(\prod_{j=1}^d\lambda_j)^{\frac{1}{d}}}Li​=(∏j=1d​λj​)d1​λi​L​
  3. 通过上一步确定的Trust Region为TR(x∗)=(x1∗+L1,x2∗+L2,...,xd∗+Ld)\text{TR}(x^*)=(x_1^*+L_1,x_2^*+L_2,...,x^*_d+L_d)TR(x∗)=(x1∗​+L1​,x2∗​+L2​,...,xd∗​+Ld​),从中select出qqq个候选点(candidates)
  4. 定义τsucc\tau_{succ}τsucc​和τfail\tau_{fail}τfail​中的success和failure,一次“成功”为一个候选点的观测值大于y∗y^*y∗,一次“失败”为一个候选点的观测值小于y∗y^*y∗然后返回到GP model进行拟合

这就是一个single local trust region BO中采集函数的具体流程。(省略了GP的拟合)

2.2 全局信赖域BO(TuRBO)

TuRBO同时维持着m个trust regions,TRlwherel∈{1,...,m}\text{TR}_l ~where~l\in\{1,...,m\}TRl​ where l∈{1,...,m}。从这m个trust regions选择第iii个候选点(candidate)的公式如下:

x(i)∈arg max⁡larg max⁡x∈TRlfl(i)wherefl(i)∼GPl(μl(x),σl(x))x^{(i)}\in \argmax_l\argmax_{x\in \text{TR}_l}f_l^{(i)}~where~f_l^{(i)}\sim \mathcal{GP}_l(\mu_l(x),\sigma_l(x))x(i)∈largmax​x∈TRl​argmax​fl(i)​ where fl(i)​∼GPl​(μl​(x),σl​(x))

先解释一下,后面第三章节直接上代码对应了。

  1. 第一个argmax,意味着先从mmm个TR中任选一个,比如lll
  2. 选好了第lll个TRl\text{TR}_lTRl​,那里有一个回归好的高斯回归模型GPl\mathcal GP_lGPl​,从这个TRl\text{TR}_lTRl​中用伪随机数算法Sobel生成一些点xxx,把这些点用GPl\mathcal GP_lGPl​来采样得到它们的function values即fl(x)f_l(x)fl​(x)
  3. 从这些fl(x)f_l(x)fl​(x)中argmax出最大值点值对即(xl,f(xl))(x_l,f(x_l))(xl​,f(xl​)),然后每个TR都这么做,就有m个这样点对,从中选出最大的当作候选点xl(i)x_l^{(i)}xl(i)​

三、TuRBO代码分析

只分析turbo_m.py中最主要的代码:

第一部分主要是对n个trust regions进行初始化:

# 初始化n个信赖域的数据
for i in range(self.n_trust_regions):# 以latin_hypercube的方式生成n_init个初始点X_init = latin_hypercube(self.n_init, self.dim)# 对X_init进行标准化X_init = from_unit_cube(X_init, self.lb, self.ub)# 对X_init进行评估/观测/计算/测量fX_init = np.array([[self.f(x)] for x in X_init])# 存放数据信息self.X = np.vstack((self.X, X_init))self.fX = np.vstack((self.fX, fX_init))self._idx = np.vstack((self._idx, i * np.ones((self.n_init, 1), dtype=int)))# count 评估次数self.n_evals += self.n_init

第二部分

# 主循环的条件:最大评估次数max_evals
while self.n_evals < self.max_evals:# 创建候选点的容器X_cand = np.zeros((self.n_trust_regions, self.n_cand, self.dim))y_cand = np.inf * np.ones((self.n_trust_regions, self.n_cand, self.batch_size))# 对n个regions,各自生成候选点即_create_candiates这个函数for i in range(self.n_trust_regions):# 这里是一些对数据维度的处理细节idx = np.where(self._idx == i)[0]   X = deepcopy(self.X[idx, :])X = to_unit_cube(X, self.lb, self.ub)fX = deepcopy(self.fX[idx, 0].ravel())n_training_steps = 0 if self.hypers[i] else self.n_training_steps# 在TR内利用sobolEngine生成随机数,然后利用GP采样得到function value,得到的候选点X_cand[i, :, :], y_cand[i, :, :], self.hypers[i] =self._create_candidates(X, fX, length=self.length[i], n_training_steps=n_training_steps, hypers=self.hypers[i])# 选出候选点,这一步对应第二章TuRBO理论介绍的X_next, idx_next = self._select_candidates(X_cand, y_cand)# 标准化还原X_next = from_unit_cube(X_next, self.lb, self.ub)# 评估候选点fX_next = np.array([[self.f(x)] for x in X_next])# 更新TRfor i in range(self.n_trust_regions):idx_i = np.where(idx_next == i)[0]if len(idx_i) > 0:self.hypers[i] = {}  fX_i = fX_next[idx_i]# 调整子域(信赖域)的长度self._adjust_length(fX_i, i)

参考资料

  • [TuRBO Paper : Scalable Global Optimization via Local Bayesian Optimization (NIPS 2019)]
  • [Github Code]
  • GPyTorch Docs (常用库)

TuRBO(2019NIPS)—贝叶斯优化的应用相关推荐

  1. 贝叶斯优化优秀论文总结目录

    持续更新中,论文均来自该领域的优秀会议或期刊,涉及的领域主要是贝叶斯优化,离散贝叶斯优化.本人才疏学浅,若读者发现有不对的地方,欢迎留言评论指正. Bayesian optimization 标题 发 ...

  2. 工业黑箱问题怎么解?高维搜索空间上的多目标贝叶斯优化

    Multi-Objective Bayesian Optimization over High-Dimensional Search Spaces(2022) 摘 要 许多现实世界的科学和工业应用需要 ...

  3. 贝叶斯优化(深度剖析)

    Bayesian Optimization(超长预警) 概述 一.Objective Function的统计量(GPR) 二.采集函数Acquisition Function 2.1 Probabil ...

  4. 论文: 贝叶斯优化方法和应用综述(1)--------陈述设计类问题举例子,与 model-free优化计算的对比

    陈述:     就是想看一下贝叶斯学派的陈述,从不同的学派的对比,看看有什么优缺点,然后自己思考下.  摘要: 通过设计恰当的概率代理模型和采集函数,贝叶斯优化框架只需经过少数次目标函数评估即可获得理 ...

  5. 超参数调优河伯、组合优化器CompBO,华为诺亚开源贝叶斯优化库

    视学算法报道 编辑:陈萍.杜伟 华为诺亚开源了一个贝叶斯优化的库,该库包含三个部分:河伯.T-LBO.CompBO. 贝叶斯优化可以说是一种黑盒优化算法,该算法用于求解表达式未知函数的极值问题.因其具 ...

  6. 用简单术语让你看到贝叶斯优化之美

    选自Medium 作者:Andre Ye 机器之心编译 编辑:Panda 贝叶斯优化是机器学习超参数优化的常用技术之一,本文不会使用艰深的数学论证,而是通过简单的术语带你领略贝叶斯优化之美. 假设有一 ...

  7. 贝叶斯优化-matlab

    当我们遇到的一个最优化问题,但是目标函数不知道,或者说目标函数是类似于黑盒子,很难用数学公式/程序写出来时,此时想要求得目标函数的极值,可以使用贝叶斯优化,其主要的适用的情景是维数不超过20维,目标是 ...

  8. 机器学习、超参数、最优超参数、网格搜索、随机搜索、贝叶斯优化、Google Vizier、Adviser

    机器学习.超参数.最优超参数.网格搜索.随机搜索.贝叶斯优化.Google Vizier.Adviser 最优超参数 选择超参数的问题在于,没有放之四海而皆准的超参数. 因此,对于每个新数据集,我们必 ...

  9. 机器学习调参与贝叶斯优化及其典型python实现hyperopt

    机器学习调参与贝叶斯优化及其典型python实现hyperopt hyperopt的详细实施参考笔者的如下文章: 使用hyperopt(Bayesian optimization)为lightGBM模 ...

最新文章

  1. 洛谷P3252 [JLOI2012]树
  2. 从词袋到Transfomer,NLP十年突破史
  3. Django的model模型
  4. 大型软件公司.net面试题!
  5. SpringBoot 路径访问控制
  6. BugkuCTF-Crypto题你喜欢下棋吗
  7. php mysql开发技术_PHP+MySQL开发技术详解—学习笔记
  8. 疲劳驾驶样本集_欧洲要求,2022年开始新车必须配备DMS(防疲劳预警)系统
  9. 微软8月补丁星期二值得关注的几个0day、几个严重漏洞及其它
  10. 推荐几个清华和交大学霸公众号,值得学习
  11. 多位专家解读工业3D打印“叫好不叫座”
  12. C语言学生信息管理系统详细设计
  13. 全国道路运输管理人员考试多选练习题库
  14. 服务器装系统鼠标键盘不能动,装系统鼠标键盘不能动
  15. 【入门】统计字符的个数
  16. mysql按照学生分组查询_MySQL分组查询
  17. 简单易懂的现代魔法——Play Framework攻略3
  18. 我“药水哥”硬气了 改行‘程序员’了
  19. JAVA 静态方法和成员方法、静态方法的调用
  20. Mac OS X 键盘快捷键

热门文章

  1. 微信小程序的个人健康管理系统 uniapp
  2. 高级语言与计算机硬件有关吗,计算机高级语言是与计算机硬件有关的语言。
  3. App市场运营三步曲
  4. github使用tokens的方法
  5. NSFC地区基金,要比想象中难拿吗 【附2022年NSFC申请空白模板】
  6. 闲得无聊,随手来一发,就当随笔罢
  7. Spring来一发 --- 目录
  8. IDEA代码生成Generate
  9. 5w每秒的高并发优化:电商秒杀与抢购
  10. Linux安装JDK及Maven