GPflow / GPflowOpt

Bayesian Optimization using GPflow

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Query points do not change

mccajm opened this issue · comments

Hello,

I have the following code:

def objective(x):
    # this returns MSE of shape (1, 1)

size_x = (-6.2, 11.4)
size_y = (3.4, 6.9)
domain = np.sum([GPflowOpt.domain.ContinuousParameter(f'mux{i}', *size_x) for i in range(7)])
domain += np.sum([GPflowOpt.domain.ContinuousParameter(f'muy{i}', *size_y) for i in range(7)])
domain += GPflowOpt.domain.ContinuousParameter('offset', 34, 48)

design = GPflowOpt.design.RandomDesign(200, domain)
X = design.generate()
Y = np.array([obj(x.reshape(1, -1)) for x in X]).reshape(-1, 1)
model = GPflow.gpr.GPR(X, Y, GPflow.kernels.RBF(15, ARD=True, lengthscales=X.std(axis=0)))
model.likelihood.variance = 1e-3
acquisition = GPflowOpt.acquisition.ExpectedImprovement(model)
optimizer = GPflowOpt.BayesianOptimizer(domain, acquisition)
optimizer.optimize(objective, n_iter=500)

The first 200 points are random, and then the objective function gets called with the same query point repeatedly. Am I doing anything obviously wrong and how can I debug this?

I'm using TF 1.2, Python 3.6, and the master branch of GPflowOpt (6c1a92d).

Thanks,
Adam

Hi @mccajm ,

The way you are using GPflowOpt is perfectly fine. Given that I don't have the objective I can not check for myself what is wrong,
My two first guesses:

  • A flat model, due to hyperparameter optimization issues
  • Failure to find the EI optimum (optimizer ending prematurely and returning the starting point due to no improvement in any direction).

Seeing the dimensionality is 15 with an ARD kernel, both issues are likely. BO beyond 10 dimensions can be tricky, and unfortunately plotting won't give us an idea.

Breaking this down in steps. You could verify the initial model. I saw you have ARD set to True, so you have to get quite a lot of lengthscales right. This code checks the model and the MSE:

X = design.generate()
Y = np.array([obj(x.reshape(1, -1)) for x in X]).reshape(-1, 1)
model = GPflow.gpr.GPR(X, Y, GPflow.kernels.RBF(15, ARD=True, lengthscales=X.std(axis=0)))
model.likelihood.variance = 1e-3
model.optimize()
print(model)
m, v = model.predict_f(X)
print('MSE: {0}'.format(np.mean((Y-m)**2)))
print(np.var(Y))

Then next, you do not configure an optimizer for the acquisition function optimization. This means it will go with the default which is scipy.minimize. As described previously, this can end prematurely in 15D. You can verify this by setting optimisation_verb = True in the gpflowrc file. L-BFGS-B should report this clearly. What is the point that is repeatedly evaluated? If it is the center of your 15D domain it means its definitely a failing optimization of the acquisition function.
My suggestion to overcome this:

opt = GPflowOpt.optim.StagedOptimizer([GPflowOpt.optim.MCOptimizer(domain, 200), 
                                                                 GPflowOpt.optim.SciPyOptimizer(domain)])
optimizer = GPflowOpt.BayesianOptimizer(domain, acquisition, optimizer=opt)

This will first evaluate the acquisition function in 200 random points, then apply SciPy on the most promising. For 15D you might even raise the number of random points. If you look at the optimization surface of EI in https://github.com/GPflow/GPflowOpt/blob/init_docs/doc/source/notebooks/constrained_bo.ipynb you get an idea of the issue: in 15D the EI optimum can be well hidden, surrounded by flat areas in every direction.

Thank you Joachim for the great answer. I disabled ARD as the length scales were reasonably close and sampled points. This resolved the issue.