Suggest-Evaluate-Register paradigm not working with constraints
Vidarrwin opened this issue · 3 comments
Describe the bug
When implementing optimization using the Suggest-Evaluate-Register paradigm, second call to optimizer.suggest(util_func)
in loop results in TypeError: 'NoneType' object is not subscriptable
.
To Reproduce
I used the notebook constraints.ipynb
to try and implement the Suggest-Evaluate-Register paradigm with constraints in the following issue_snippet.py
file:
import numpy as np
from bayes_opt import BayesianOptimization
from bayes_opt import UtilityFunction
import matplotlib.pyplot as plt
from scipy.optimize import NonlinearConstraint
def target_function(x, y):
# Gardner is looking for the minimum, but this packages looks for maxima, thus the sign switch
return np.cos(2 * x) * np.cos(y) + np.sin(x)
def constraint_function(x, y):
return np.cos(x) * np.cos(y) - np.sin(x) * np.sin(y)
constraint_limit = 0.5
constraint = NonlinearConstraint(constraint_function, -np.inf, constraint_limit)
# Bounded region of parameter space
pbounds = {"x": (0, 6), "y": (0, 6)}
optimizer = BayesianOptimization(
f=None,
constraint=constraint,
pbounds=pbounds,
verbose=0, # verbose = 1 prints only when a maximum is observed, verbose = 0 is silent
random_state=1,
)
util_func = UtilityFunction()
for i in range(20):
next_point = optimizer.suggest(util_func)
target = target_function(**next_point)
constraint_value = constraint_function(next_point["x"], next_point["y"])
optimizer.register(
params=next_point, target=target, constraint_value=constraint_value
)
print(optimizer.max)
Output
File "C:\bo\issue_snippet.py", line 34, in <module>
next_point = optimizer.suggest(util_func)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\bo\.env\Lib\site-packages\bayes_opt\bayesian_optimization.py", line 276, in suggest
y_max_params=self._space.params_to_array(self._space.max()['params']))
~~~~~~~~~~~~~~~~~^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
Expected output
{'target': np.float64(1.763860854788071), 'params': {'x': np.float64(1.4289811571617572), 'y': np.float64(2.5083402722272017)}, 'constraint': np.float64(-0.6997643336023384)
(or at least some result)
Expected behavior
The for
loop should work and give a result.
Screenshots
If applicable, add screenshots to help explain your problem.
Environment
- OS: Windows
python
Version 3.12.5numpy
Version 2.1.1scipy
Version 1.14.1bayesian-optimization
Version 1.5.1
Additional context
Hello there!
First thank you for your work :)
I wanted to optimize a constrained black-box model using your BO module, and especially the Suggest-Evaluate-Register paradigm, so I first tried to change one of your constraint examples using this paradigm.
The constraints.ipynb
notebook works perfectly fine using the optimize.maximise()
call.
Unfortunately I could not make it work using the other paradigm.
Here is some information that might help with isue:
-
With the above code, the first iteration of the
for
loop works, but the second call tooptimizer.suggest(util_func)
fails and results inTypeError: 'NoneType' object is not subscriptable
.It seems that the
TargetSpace.max
function returnsNone
, even in the second iteration of the loop.
The callself._target_max()
in theTargetSpace.max
at line439
seems to only returnNone
.
It feels like the first target value computed and given in the first iteration tooptimizer.register(params=next_point, target=target, constraint_value=constraint_value)
is not kept.
I hope it was clear enough, thank you for your attention.
Hey @Vidarrwin,
this can happen if the optimizer has no valid (= constraints fulfilled) point at the time of the suggest step. We fixed this on master already, but not in the released version. The workaround here would be to increase the number of randomly sampled points to prime the optimizer so that there's at least one valid point.
Thank you for your help!
The random state fixed a first point which did not fulfill the constraint.
I changed it and it now works!
glad to hear. Feel free to let us know if you run into other issues.