GpyOpt忽略了约束。指定它们的正确方法是什么?

时间:2018-03-20 17:06:52

标签: python optimization constraints bayesian gpyopt

我想在GpyOpt中运行约束优化。说,我想最小化

其中

s.t。至少有一个非零,并且不超过3可以等于1.所以我指定约束:

根据参考手册here,我们可以使用numpy函数指定约束。建议here我们可以在调用BayesianOptimization时指定约束。所以我在GpyOpt中使用以下代码

表达了这一点
import numpy as np
import GPyOpt
from GPyOpt.methods import BayesianOptimization

seed = 6830
np.random.seed(seed)

def f(x):
    print(np.sum(x[:]), end=" ") # check if constraints are satisfied
    z = np.sum(x)
    return z**2

bounds = [{"name": "x", "type" : "discrete", 
           "domain" : (0, 1), "dimensionality": 10}]

constraints = [{'name' : 'more_than_0','constraint' : '-np.sum(x[:]) + 0.1'},
               {'name' : 'less_than_3','constraint' : 'np.sum(x[:]) - 3'}]

bopt = BayesianOptimization(f, domain=bounds, constraints=constraints)
bopt.run_optimization(max_iter=10)

但是,看起来GpyOpt忽略了这些约束,因为我在控制台中得到以下输出:

6.0 1.0 5.0 7.0 3.0 2.0 2.0 0.0 1.0 3.0 1.0 1.0 1.0 0.0 2.0 

包含高于3和0的值。

如果我明确地将np.sum(x[:])写为x[:, 0] + x[:, 1] + ...,则行为不会改变。

如果我指定连续域,则仍会违反约束。

传递约束的正确方法是什么,这样才不会被忽略?

我正在使用GpyOpt版本1.2.1。

更新: np.sum(x, 1)代替np.sum(x[:])无法解决问题。

我正在使用Python 3.6.3和numpy 1.14.2以及通过pip安装GPyOpt 1.2.1。

1 个答案:

答案 0 :(得分:2)

我不确定你是在总结x的权利。约束表达式应该在整个X上工作,并为每个数据点输出一个值数组,然后根据约束检查它们。

当我将两个表达式中的求和更改为:

np.sum(x, axis=1)

并保持代码完整无缺,输出为:

1.0 2.0 1.0 2.0 2.0 2 2 2 2 1 2 2 1 2 1

没有违规行为。