Skip to content

Commit 5bc8ad4

Browse files
committed
Add minimum_window for sequential domain reduction
Only update the domains if you are within the searching phase of the optimizer. If the SequentialDomainReduction tool wants to flip the bounds make sure they are sorted correctly.
1 parent 59ecbef commit 5bc8ad4

File tree

4 files changed

+99
-42
lines changed

4 files changed

+99
-42
lines changed

bayes_opt/bayesian_optimization.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,9 @@ def maximize(self,
270270

271271
self.probe(x_probe, lazy=False)
272272

273-
if self._bounds_transformer:
273+
if self._bounds_transformer and iteration > 0:
274+
# The bounds transformer should only modify the bounds after the init_points points (only for the true
275+
# iterations)
274276
self.set_bounds(
275277
self._bounds_transformer.transform(self._space))
276278

bayes_opt/domain_reduction.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Optional, Union, List
2+
13
import numpy as np
24
from .target_space import TargetSpace
35

@@ -25,18 +27,26 @@ def __init__(
2527
self,
2628
gamma_osc: float = 0.7,
2729
gamma_pan: float = 1.0,
28-
eta: float = 0.9
30+
eta: float = 0.9,
31+
minimum_window: Optional[Union[List[float], float]] = 0.0
2932
) -> None:
3033
self.gamma_osc = gamma_osc
3134
self.gamma_pan = gamma_pan
3235
self.eta = eta
33-
pass
36+
self.minimum_window_value = minimum_window
3437

3538
def initialize(self, target_space: TargetSpace) -> None:
3639
"""Initialize all of the parameters"""
3740
self.original_bounds = np.copy(target_space.bounds)
3841
self.bounds = [self.original_bounds]
3942

43+
# Set the minimum window to an array of length bounds
44+
if isinstance(self.minimum_window_value, list) or isinstance(self.minimum_window_value, np.ndarray):
45+
assert len(self.minimum_window_value) == len(target_space.bounds)
46+
self.minimum_window = self.minimum_window_value
47+
else:
48+
self.minimum_window = [self.minimum_window_value] * len(target_space.bounds)
49+
4050
self.previous_optimal = np.mean(target_space.bounds, axis=1)
4151
self.current_optimal = np.mean(target_space.bounds, axis=1)
4252
self.r = target_space.bounds[:, 1] - target_space.bounds[:, 0]
@@ -89,6 +99,14 @@ def _trim(self, new_bounds: np.array, global_bounds: np.array) -> np.array:
8999
variable[0] = global_bounds[i, 0]
90100
if variable[1] > global_bounds[i, 1]:
91101
variable[1] = global_bounds[i, 1]
102+
for i, entry in enumerate(new_bounds):
103+
if entry[0] > entry[1]:
104+
new_bounds[i, 0] = entry[1]
105+
new_bounds[i, 1] = entry[0]
106+
window_width = abs(entry[0] - entry[1])
107+
if window_width < self.minimum_window[i]:
108+
new_bounds[i, 0] -= (self.minimum_window[i] - window_width) / 2.0
109+
new_bounds[i, 1] += (self.minimum_window[i] - window_width) / 2.0
92110

93111
return new_bounds
94112

examples/domain_reduction.ipynb

Lines changed: 36 additions & 39 deletions
Large diffs are not rendered by default.

tests/test_seq_domain_red.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import numpy as np
2+
13
from bayes_opt import SequentialDomainReductionTransformer
24
from bayes_opt import BayesianOptimization
35

@@ -64,3 +66,41 @@ def reset(self):
6466
assert len(standard_optimizer.space) == len(mutated_optimizer.space)
6567
assert not (standard_optimizer._space.bounds ==
6668
mutated_optimizer._space.bounds).any()
69+
70+
def test_minimum_window_is_kept():
71+
bounds_transformer = SequentialDomainReductionTransformer(minimum_window=1.0)
72+
pbounds = {'x': (-0.5, 0.5), 'y': (-1.0, 0.0)}
73+
mutated_optimizer = BayesianOptimization(
74+
f=black_box_function,
75+
pbounds=pbounds,
76+
verbose=0,
77+
random_state=1,
78+
bounds_transformer=bounds_transformer
79+
)
80+
81+
mutated_optimizer.maximize(
82+
init_points=2,
83+
n_iter=10,
84+
)
85+
window_width = np.diff(bounds_transformer.bounds)
86+
assert np.isclose(np.min(window_width), 1.0)
87+
88+
89+
def test_minimum_window_array_is_kept():
90+
window_ranges = [1.0, 0.5]
91+
bounds_transformer = SequentialDomainReductionTransformer(minimum_window=window_ranges)
92+
pbounds = {'x': (-0.5, 0.5), 'y': (-1.0, 0.0)}
93+
mutated_optimizer = BayesianOptimization(
94+
f=black_box_function,
95+
pbounds=pbounds,
96+
verbose=0,
97+
random_state=1,
98+
bounds_transformer=bounds_transformer
99+
)
100+
101+
mutated_optimizer.maximize(
102+
init_points=2,
103+
n_iter=10,
104+
)
105+
window_widths = np.diff(bounds_transformer.bounds)
106+
assert np.all(np.isclose(np.squeeze(np.min(window_widths, axis=0)), window_ranges))

0 commit comments

Comments
 (0)