AbstractInitialDesign(
scenario: Scenario,
n_configs: int | None = None,
n_configs_per_hyperparameter: int | None = 10,
max_ratio: float = 0.25,
additional_configs: list[Configuration] = None,
seed: int | None = None,
)
Base class for initial design strategies that evaluates multiple configurations.
Parameters
scenario : Scenario
n_configs : int | None, defaults to None
Number of initial configurations (disables the arguments n_configs_per_hyperparameter
).
n_configs_per_hyperparameter: int, defaults to 10
Number of initial configurations per hyperparameter. For example, if my configuration space covers five
hyperparameters and n_configs_per_hyperparameter
is set to 10, then 50 initial configurations will be
samples.
max_ratio: float, defaults to 0.25
Use at most scenario.n_trials
* max_ratio
number of configurations in the initial design.
Additional configurations are not affected by this parameter.
additional_configs: list[Configuration], defaults to []
Adds additional configurations to the initial design.
seed : int | None, default to None
Source code in smac/initial_design/abstract_initial_design.py
| def __init__(
self,
scenario: Scenario,
n_configs: int | None = None,
n_configs_per_hyperparameter: int | None = 10,
max_ratio: float = 0.25,
additional_configs: list[Configuration] = None,
seed: int | None = None,
):
self._configspace = scenario.configspace
if seed is None:
seed = scenario.seed
self.use_default_config = scenario.use_default_config
self._seed = seed
self._rng = np.random.RandomState(seed)
self._n_configs_per_hyperparameter = n_configs_per_hyperparameter
# make sure that additional configs is not a mutable default value
# this avoids issues
if additional_configs is None:
additional_configs = []
if self.use_default_config:
default_config = self._configspace.get_default_configuration()
default_config.origin = "Initial Design: Default configuration"
additional_configs.append(default_config)
self._additional_configs = additional_configs
n_params = len(list(self._configspace.values()))
if n_configs is not None:
logger.info("Using `n_configs` and ignoring `n_configs_per_hyperparameter`.")
self._n_configs = n_configs
elif n_configs_per_hyperparameter is not None:
self._n_configs = n_configs_per_hyperparameter * n_params
else:
raise ValueError(
"Need to provide either argument `n_configs` or "
"`n_configs_per_hyperparameter` but provided none of them."
)
# If the number of configurations is too large, we reduce it
_n_configs = int(max(1, min(self._n_configs, (max_ratio * scenario.n_trials))))
if self._n_configs != _n_configs:
logger.info(
f"Reducing the number of initial configurations from {self._n_configs} to "
f"{_n_configs} (max_ratio == {max_ratio})."
)
self._n_configs = _n_configs
# We allow no configs if we have additional configs
if n_configs is not None and n_configs == 0 and len(additional_configs) > 0:
self._n_configs = 0
if self._n_configs + len(additional_configs) > scenario.n_trials:
raise ValueError(
f"Initial budget {self._n_configs} cannot be higher than the number of trials {scenario.n_trials}."
)
|
Returns the meta data of the created object.
select_configurations
select_configurations() -> list[Configuration]
Selects the initial configurations. Internally, _select_configurations
is called,
which has to be implemented by the child class.
Returns
configs : list[Configuration]
Configurations from the child class.
Source code in smac/initial_design/abstract_initial_design.py
| def select_configurations(self) -> list[Configuration]:
"""Selects the initial configurations. Internally, `_select_configurations` is called,
which has to be implemented by the child class.
Returns
-------
configs : list[Configuration]
Configurations from the child class.
"""
configs: list[Configuration] = []
if self._n_configs == 0:
logger.info("No initial configurations are used.")
else:
configs += self._select_configurations()
# Adding additional configs
configs += self._additional_configs
for config in configs:
if config.origin is None:
config.origin = "Initial design"
# Removing duplicates
# (Reference: https://stackoverflow.com/questions/7961363/removing-duplicates-in-lists)
configs = list(OrderedDict.fromkeys(configs))
logger.info(
f"Using {len(configs) - len(self._additional_configs)} initial design configurations "
f"and {len(self._additional_configs)} additional configurations."
)
return configs
|