Python中的贝叶斯优化包GPyOpt


什么是贝叶斯优化?

贝叶斯优化是一种使用称为高斯过程的机器学习方法优化某些功能的方法,该方法执行贝叶斯内核回归。贝叶斯优化的优点是多种多样的,例如,它可以应用于输入不连续(不可微分)的函数,并且对于具有局部解的函数很强。由于这些优点,认为将来可以将其应用于各种问题。在这里,我们将说明如何使用GPyOpt,它是在Python中执行贝叶斯优化的软件包。

GPyOpt安装

使用anaconda作为环境。您需要最新的scipy和GPy(高斯过程)软件包。

1
2
3
$ conda update scipy
$ pip install GPy
$ pip install gpyopt

一维输入的功能优化(说明)

首先,让我们优化输入为一维的非线性函数。
这次,我们将在$ 0 \\\\ leq x \\\\ leq 10 $范围内最小化$ f(x)= \\\\ cos(1.5x)0.1x $的函数。
image

贝叶斯优化首先在给定范围内随机采样一些输入。接下来,将输入样本传递给函数并获得输出样本。然后,使用该样本,在高斯过程中执行回归。在此图中,绿色是要优化的函数,蓝色是在高斯过程中回归的函数。
image

现在,让我们找出将函数最小化的地方。
我们要做的是确定最小的x并找到y,依此类推。关于x可能为最小值的各种标准,但这一次,在该图的蓝色区域中将x扩展到最小的y,我将其设置为x可能为最小值。仅给定红点的数据,该蓝色区域是可能包含绿线的区域。

现在,让我们通过这种方法采样一个。
image
采样一个后,重要的是蓝色区域正在改变。然后,在该状态下,通过执行采样→蓝色区域的更新→采样→蓝色区域的更新→???,可以找到最小为$ f(x)$的x。

然后,显示一些采样后的数字。实际上在$ x = 2 $附近采样了很多样本??,而最优解是在该采样中实际上使$ f(x)$最??小的解决方案。
image

一维函数优化(GPyOpt)

让我们用GPyOpt来做。

首先,导入。

1
2
3
import GPy
import GPyOpt
import numpy as np

然后定义要优化的功能。在这里,您可以指定numpy函数。

1
2
3
4
5
def f(x):
    '''
    今回最適化する非線形関数
    '''
    return np.cos(1.5*x) + 0.1*x

现在,让我们首先定义x的域。 \\'type \\':\\'continuous \\'表示它是连续的,而\\'domain \\':(0,10)表示它是$ 0 \\\\ leq x \\\\ leq 10 $。
在第二行中,我们获得用于贝叶斯优化的对象。 f是您要优化的函数,domain是您之前定义的域,initial_design_numdata是首先获取的样本数。 Acquisition_type指的是如何选择下一个要采样的x(\\'LCB \\'选择蓝色区域最小化的位置)。

1
2
bounds = [{'name': 'x', 'type': 'continuous', 'domain': (0,10)}]
myBopt = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds,initial_design_numdata=5,acquisition_type='LCB')

然后,使用以下命令重复采样以进行优化。 max_iter指示采样数。

1
myBopt.run_optimization(max_iter=15)

显示最佳解决方案。

1
2
print(myBopt.x_opt) #[ 2.05769988]
print(myBopt.fx_opt) #[-0.79271554]

其他可能使用的功能变量

1
2
3
myBopt.model.model #ベイズ最適化で使っているガウス過程のモデル(GPyのオブジェクト)
myBopt.model.model.predict #ガウス過程の回帰の関数
myBopt.X,myBopt.Y #サンプリングしたxとy

二维输入的功能优化

贝叶斯优化也可以在多个维度上应用。在此,执行二维贝叶斯优化。
另外,由于输入变量可能是离散变量,因此我将对一维使用离散变量。

函数是$ f(x)= \\\\ log(10.5-x_0)0.1 \\\\ sin(15x_0)$(当$ x_1 = 0 $时)和$ f(x)当$ x_1 = 1 $。 \\ cos(1.5x_0)0.1x_0 $。此外,我们将在$ 0 \\\\ leq x_1 \\\\ leq 10 $($ x_0 $为0或1)的范围内将其最小化。

image

经过

优化后,它将如下图所示。

image

让我们用GPyOpt来做。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import GPy
import GPyOpt
import numpy as np

def f(x):
    '''
    今回最適化する非線形関数
    '''
    x0,x1 = x[:,0],x[:,1]
    f0 = np.log(10.5-x0) + 0.1*np.sin(15*x0)
    f1 = np.cos(1.5*x0) + 0.1*x0
    return (1-x1)*f0 + x1*f1

bounds = [{'name': 'x0', 'type': 'continuous', 'domain': (0,10)},
          {'name': 'x1', 'type': 'discrete', 'domain': (0,1)}]
myBopt = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds)

myBopt.run_optimization(max_iter=30)

与一维情况没什么不同。发生的变化是该函数还具有两个输入,并且界限是一个包含两个元素的列表。 \\'type \\':\\'discrete \\'代表选择,0或1。

显示最佳解决方案。

1
2
print(myBopt.x_opt) #[ 2.0539031  1.       ]
print(myBopt.fx_opt) #[-0.7927657]