Skip to content

Commit 573664b

Browse files
authored
Merge: Add Continuous Optimization Controls to BotorchRecommender (#389)
BotorchRecommender now has the optional keywords `n_restarts` and `n_raw_samples` which control continuous optimization behavior and can be increased if the user desires. The defaults have been slighlty increased as well as previous values seemed extremely low.
2 parents 4a92743 + 3f5f48f commit 573664b

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- `n_restarts` and `n_raw_samples` keywords to configure continuous optimization
10+
behavior for `BotorchRecommender`
11+
812
### Fixed
913
- Leftover attrs-decorated classes are garbage collected before the subclass tree is
1014
traversed, avoiding sporadic serialization problems
@@ -23,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2327
- Leftover attrs-decorated classes are garbage collected before the subclass tree is
2428
traversed, avoiding sporadic serialization problems
2529

26-
### Deprecated
30+
### Deprecations
2731
- `ContinuousLinearEqualityConstraint` and `ContinuousLinearInequalityConstraint`
2832
replaced by `ContinuousLinearConstraint` with the corresponding `operator` keyword
2933

baybe/recommenders/pure/bayesian/botorch.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from typing import Any, ClassVar
66

77
import pandas as pd
8-
from attr.converters import optional
98
from attrs import define, field
9+
from attrs.converters import optional as optional_c
10+
from attrs.validators import gt, instance_of
1011

1112
from baybe.acquisition.acqfs import qThompsonSampling
1213
from baybe.exceptions import (
@@ -50,12 +51,12 @@ class BotorchRecommender(BayesianRecommender):
5051
# Object variables
5152
sequential_continuous: bool = field(default=False)
5253
"""Flag defining whether to apply sequential greedy or batch optimization in
53-
**continuous** search spaces. (In discrete/hybrid spaces, sequential greedy
54-
optimization is applied automatically.)
54+
**continuous** search spaces. In discrete/hybrid spaces, sequential greedy
55+
optimization is applied automatically.
5556
"""
5657

5758
hybrid_sampler: DiscreteSamplingMethod | None = field(
58-
converter=optional(DiscreteSamplingMethod), default=None
59+
converter=optional_c(DiscreteSamplingMethod), default=None
5960
)
6061
"""Strategy used for sampling the discrete subspace when performing hybrid search
6162
space optimization."""
@@ -64,6 +65,16 @@ class BotorchRecommender(BayesianRecommender):
6465
"""Percentage of discrete search space that is sampled when performing hybrid search
6566
space optimization. Ignored when ``hybrid_sampler="None"``."""
6667

68+
n_restarts: int = field(validator=[instance_of(int), gt(0)], default=10)
69+
"""Number of times gradient-based optimization is restarted from different initial
70+
points. **Does not affect purely discrete optimization**.
71+
"""
72+
73+
n_raw_samples: int = field(validator=[instance_of(int), gt(0)], default=64)
74+
"""Number of raw samples drawn for the initialization heuristic in gradient-based
75+
optimization. **Does not affect purely discrete optimization**.
76+
"""
77+
6778
@sampling_percentage.validator
6879
def _validate_percentage( # noqa: DOC101, DOC103
6980
self, _: Any, value: float
@@ -168,8 +179,8 @@ def _recommend_continuous(
168179
acq_function=self._botorch_acqf,
169180
bounds=torch.from_numpy(subspace_continuous.comp_rep_bounds.values),
170181
q=batch_size,
171-
num_restarts=5, # TODO make choice for num_restarts
172-
raw_samples=10, # TODO make choice for raw_samples
182+
num_restarts=self.n_restarts,
183+
raw_samples=self.n_raw_samples,
173184
equality_constraints=[
174185
c.to_botorch(subspace_continuous.parameters)
175186
for c in subspace_continuous.constraints_lin_eq
@@ -252,8 +263,8 @@ def _recommend_hybrid(
252263
acq_function=self._botorch_acqf,
253264
bounds=torch.from_numpy(searchspace.comp_rep_bounds.values),
254265
q=batch_size,
255-
num_restarts=5, # TODO make choice for num_restarts
256-
raw_samples=10, # TODO make choice for raw_samples
266+
num_restarts=self.n_restarts,
267+
raw_samples=self.n_raw_samples,
257268
fixed_features_list=fixed_features_list,
258269
equality_constraints=[
259270
c.to_botorch(

docs/userguide/recommenders.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,21 @@ for various acquisition functions.
3838
* The **[`BotorchRecommender`](baybe.recommenders.pure.bayesian.botorch.BotorchRecommender)**
3939
is a powerful recommender based on BoTorch's optimization engine that can be applied
4040
to all kinds of search spaces. In continuous spaces, its `sequential_continuous` flag
41-
allows to chose between greedy sequential optimization and batch optimization as the
41+
allows to choose between greedy sequential optimization and batch optimization as the
4242
underlying point generation mode. In discrete/hybrid spaces, sequential greedy
4343
selection is the only available mode and is thus activated automatically.
4444

4545
Note that the recommender performs a brute-force search when applied to hybrid search
46-
spaces, as it optimizes the continuous part of the space while exhaustively searching
47-
choices in the discrete subspace. You can customize this behavior to only sample a
48-
certain percentage of the discrete subspace via the `sample_percentage` attribute and
49-
to choose different sampling algorithms via the `hybrid_sampler` attribute.
50-
46+
spaces, as it does gradient-based optimization in the continuous part of the space
47+
while exhaustively evaluating configurations of the discrete subspace. You can customize this
48+
behavior to only sample a certain percentage of the discrete subspace via the
49+
`sample_percentage` attribute and to choose different sampling algorithms via the
50+
`hybrid_sampler` attribute.
51+
52+
The gradient-based optimization part can also further be controlled by the
53+
`n_restarts` and `n_raw_samples` keywords. For details, please refer
54+
to [BotorchRecommender](baybe.recommenders.pure.bayesian.botorch.BotorchRecommender).
55+
5156
An example on using this recommender in a hybrid space can be found
5257
[here](./../../examples/Backtesting/hybrid).
5358

0 commit comments

Comments
 (0)