EmuKit/emukit

Batch sizes do not work in Bayesian Optimization Loop

iRove108 opened this issue · 6 comments

The test_bayesian_optimization_loop.py code here throws an error for me when batch size > 1.

I placed the following code into a Python file and ran it.

import GPy
import numpy as np

from emukit.bayesian_optimization.acquisitions import ExpectedImprovement
from emukit.bayesian_optimization.loops import BayesianOptimizationLoop
from emukit.core.continuous_parameter import ContinuousParameter
from emukit.core.interfaces import IModel
from emukit.core.loop import FixedIterationsStoppingCondition, UserFunctionWrapper
from emukit.core.parameter_space import ParameterSpace
from emukit.model_wrappers.gpy_model_wrappers import GPyModelWrapper

def f(x):
    return x ** 2

batch_size = 3
n_init = 5
n_iterations = 5

x_init = np.random.rand(n_init, 1)
y_init = np.random.rand(n_init, 1)

# Make GPy model
gpy_model = GPy.models.GPRegression(x_init, y_init)
model = GPyModelWrapper(gpy_model)

space = ParameterSpace([ContinuousParameter("x", 0, 1)])
acquisition = ExpectedImprovement(model)

# Make loop and collect points
bo = BayesianOptimizationLoop(model=model, space=space, acquisition=acquisition, batch_size=batch_size)
bo.run_loop(UserFunctionWrapper(f), FixedIterationsStoppingCondition(n_iterations))

# Check we got the correct number of points
assert bo.loop_state.X.shape[0] == n_iterations * batch_size + n_init

# Check the obtained results
results = bo.get_results()

assert results.minimum_location.shape[0] == 1
assert results.best_found_value_per_iteration.shape[0] == n_iterations * batch_size + n_init

It gives me the following error:

 ~/opt/miniconda3/envs/delivery-sim/lib/python3.9/site-packages/emukit/bayesian_optimization/acquisitions/log_acquisition.py:25: RuntimeWarning:divide by zero encountered in log

Traceback (most recent call last):
  File "~/Dev/eco-deliveries/Delivery_problem/test.py", line 31, in <module>
    bo.run_loop(UserFunctionWrapper(f), FixedIterationsStoppingCondition(n_iterations))
  File "/Users/Alex/opt/miniconda3/envs/delivery-sim/lib/python3.9/site-packages/emukit/core/loop/outer_loop.py", line 92, in run_loop
    new_x = self.candidate_point_calculator.compute_next_points(self.loop_state, context)
  File "~/opt/miniconda3/envs/delivery-sim/lib/python3.9/site-packages/emukit/bayesian_optimization/local_penalization_calculator.py", line 85, in compute_next_points
    lipschitz_constant = _estimate_lipschitz_constant(self.parameter_space, self.model)
  File "~/opt/miniconda3/envs/delivery-sim/lib/python3.9/site-packages/emukit/bayesian_optimization/local_penalization_calculator.py", line 112, in _estimate_lipschitz_constant
    lipschitz_constant = -res.fun[0]
TypeError: 'float' object is not subscriptable

The error is thrown at this line because res.fun is not subscriptable. I'm running SciPy version 1.8.0.

Any thoughts?

thanks for the report! will have a look and get back

i can't reproduce this error. tried it locally and in Google Colab, just installing emukit and copy pasting your code. and it works fine

Thanks for the response—really appreciate the library!

I can't say anything about your local installation, but Google Colab runs Python 3.7. SciPy 1.8.0 requires Python 3.8. I suspect the error might only appear when running SciPy 1.8.0 (released recently).

For example, in the free Replit online Python interpreter:

  1. Run pip install emukit in the "shell" window
  2. Paste in the code
  3. Click run

And I get the same error.

Here's a link to an environment where I've done that.

The temporary fix might just be to use an earlier version of SciPy (I'll have to check on that). So probably not urgent, but I assume this could become relevant if anyone else tries to upgrade.

Thanks @iRove108 , managed to reproduce now. Indeed the bug only concerns scipy 1.8.0, and code works with 1.7.3

Ok, will revert my version of scipy. Thanks!

The fix is now merged, thanks @iRove108