Skip to content

Commit 8dc463f

Browse files
committed
Fix differential evolution
1 parent 9d19475 commit 8dc463f

File tree

5 files changed

+70
-59
lines changed

5 files changed

+70
-59
lines changed

smac/acquisition/maximizer/differential_evolution.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from scipy.optimize._differentialevolution import DifferentialEvolutionSolver
66

77
from smac.acquisition.maximizer import AbstractAcquisitionMaximizer
8+
from smac.utils.configspace import transform_continuous_designs
89

910
__copyright__ = "Copyright 2022, automl.org"
1011
__license__ = "3-clause BSD"
@@ -36,7 +37,9 @@ def _maximize(
3637

3738
def func(x: np.ndarray) -> np.ndarray:
3839
assert self._acquisition_function is not None
39-
return -self._acquisition_function([Configuration(self._configspace, vector=x)])
40+
return -self._acquisition_function([transform_continuous_designs(
41+
design=np.expand_dims(x, axis=0), origin="Diffrential Evolution", configspace=self._configspace
42+
)[0]])
4043

4144
ds = DifferentialEvolutionSolver(
4245
func,
@@ -58,8 +61,9 @@ def func(x: np.ndarray) -> np.ndarray:
5861

5962
_ = ds.solve()
6063
for pop, val in zip(ds.population, ds.population_energies):
61-
rc = Configuration(self._configspace, vector=pop)
62-
rc.origin = "Acquisition Function Maximizer: Differential Evolution"
64+
rc = transform_continuous_designs(
65+
design=np.expand_dims(pop, axis=0), origin="Acquisition Function Maximizer: Differential Evolution", configspace=self._configspace
66+
)[0]
6367
configs.append((-val, rc))
6468

6569
configs.sort(key=lambda t: t[0])

smac/initial_design/abstract_initial_design.py

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -155,57 +155,3 @@ def select_configurations(self) -> list[Configuration]:
155155
def _select_configurations(self) -> list[Configuration]:
156156
"""Selects the initial configurations, depending on the implementation of the initial design."""
157157
raise NotImplementedError
158-
159-
def _transform_continuous_designs(
160-
self, design: np.ndarray, origin: str, configspace: ConfigurationSpace
161-
) -> list[Configuration]:
162-
"""Transforms the continuous designs into a discrete list of configurations.
163-
164-
Parameters
165-
----------
166-
design : np.ndarray
167-
Array of hyperparameters originating from the initial design strategy.
168-
origin : str | None, defaults to None
169-
Label for a configuration where it originated from.
170-
configspace : ConfigurationSpace
171-
172-
Returns
173-
-------
174-
configs : list[Configuration]
175-
Continuous transformed configs.
176-
"""
177-
params = configspace.get_hyperparameters()
178-
for idx, param in enumerate(params):
179-
if isinstance(param, IntegerHyperparameter):
180-
design[:, idx] = param._inverse_transform(param._transform(design[:, idx]))
181-
elif isinstance(param, NumericalHyperparameter):
182-
continue
183-
elif isinstance(param, Constant):
184-
design_ = np.zeros(np.array(design.shape) + np.array((0, 1)))
185-
design_[:, :idx] = design[:, :idx]
186-
design_[:, idx + 1 :] = design[:, idx:]
187-
design = design_
188-
elif isinstance(param, CategoricalHyperparameter):
189-
v_design = design[:, idx]
190-
v_design[v_design == 1] = 1 - 10**-10
191-
design[:, idx] = np.array(v_design * len(param.choices), dtype=int)
192-
elif isinstance(param, OrdinalHyperparameter):
193-
v_design = design[:, idx]
194-
v_design[v_design == 1] = 1 - 10**-10
195-
design[:, idx] = np.array(v_design * len(param.sequence), dtype=int)
196-
else:
197-
raise ValueError("Hyperparameter not supported when transforming a continuous design.")
198-
199-
configs = []
200-
for vector in design:
201-
try:
202-
conf = deactivate_inactive_hyperparameters(
203-
configuration=None, configuration_space=configspace, vector=vector
204-
)
205-
except ForbiddenValueError:
206-
continue
207-
208-
conf.origin = origin
209-
configs.append(conf)
210-
211-
return configs

smac/initial_design/latin_hypercube_design.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from scipy.stats.qmc import LatinHypercube
66

77
from smac.initial_design.abstract_initial_design import AbstractInitialDesign
8+
from smac.utils.configspace import transform_continuous_designs
89

910
__copyright__ = "Copyright 2022, automl.org"
1011
__license__ = "3-clause BSD"
@@ -25,6 +26,6 @@ def _select_configurations(self) -> list[Configuration]:
2526

2627
lhd = LatinHypercube(d=len(params) - constants, seed=self._rng.randint(0, 1000000)).random(n=self._n_configs)
2728

28-
return self._transform_continuous_designs(
29+
return transform_continuous_designs(
2930
design=lhd, origin="Initial Design: Latin Hypercube", configspace=self._configspace
3031
)

smac/initial_design/sobol_design.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from scipy.stats.qmc import Sobol
1010

1111
from smac.initial_design.abstract_initial_design import AbstractInitialDesign
12+
from smac.utils.configspace import transform_continuous_designs
13+
1214

1315
__copyright__ = "Copyright 2022, automl.org"
1416
__license__ = "3-clause BSD"
@@ -43,6 +45,6 @@ def _select_configurations(self) -> list[Configuration]:
4345
warnings.simplefilter("ignore")
4446
sobol = sobol_gen.random(self._n_configs)
4547

46-
return self._transform_continuous_designs(
48+
return transform_continuous_designs(
4749
design=sobol, origin="Initial Design: Sobol", configspace=self._configspace
4850
)

smac/utils/configspace.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
OrdinalHyperparameter,
1717
UniformFloatHyperparameter,
1818
UniformIntegerHyperparameter,
19+
IntegerHyperparameter,
20+
NumericalHyperparameter,
1921
)
22+
from ConfigSpace.util import ForbiddenValueError, deactivate_inactive_hyperparameters
2023
from ConfigSpace.util import get_one_exchange_neighbourhood
2124

2225
__copyright__ = "Copyright 2022, automl.org"
@@ -182,6 +185,61 @@ def print_config_changes(
182185
logger.debug(msg)
183186

184187

188+
def transform_continuous_designs(
189+
design: np.ndarray, origin: str, configspace: ConfigurationSpace
190+
) -> list[Configuration]:
191+
"""Transforms the continuous designs into a discrete list of configurations.
192+
193+
Parameters
194+
----------
195+
design : np.ndarray
196+
Array of hyperparameters originating from the initial design strategy.
197+
origin : str | None, defaults to None
198+
Label for a configuration where it originated from.
199+
configspace : ConfigurationSpace
200+
201+
Returns
202+
-------
203+
configs : list[Configuration]
204+
Continuous transformed configs.
205+
"""
206+
params = configspace.get_hyperparameters()
207+
for idx, param in enumerate(params):
208+
if isinstance(param, IntegerHyperparameter):
209+
design[:, idx] = param._inverse_transform(param._transform(design[:, idx]))
210+
elif isinstance(param, NumericalHyperparameter):
211+
continue
212+
elif isinstance(param, Constant):
213+
design_ = np.zeros(np.array(design.shape) + np.array((0, 1)))
214+
design_[:, :idx] = design[:, :idx]
215+
design_[:, idx + 1 :] = design[:, idx:]
216+
design = design_
217+
elif isinstance(param, CategoricalHyperparameter):
218+
v_design = design[:, idx]
219+
v_design[v_design == 1] = 1 - 10**-10
220+
design[:, idx] = np.array(v_design * len(param.choices), dtype=int)
221+
elif isinstance(param, OrdinalHyperparameter):
222+
v_design = design[:, idx]
223+
v_design[v_design == 1] = 1 - 10**-10
224+
design[:, idx] = np.array(v_design * len(param.sequence), dtype=int)
225+
else:
226+
raise ValueError("Hyperparameter not supported when transforming a continuous design.")
227+
228+
configs = []
229+
for vector in design:
230+
try:
231+
conf = deactivate_inactive_hyperparameters(
232+
configuration=None, configuration_space=configspace, vector=vector
233+
)
234+
except ForbiddenValueError:
235+
continue
236+
237+
conf.origin = origin
238+
configs.append(conf)
239+
240+
return configs
241+
242+
185243
# def check_subspace_points(
186244
# X: np.ndarray,
187245
# cont_dims: np.ndarray | list = [],

0 commit comments

Comments
 (0)