Skip to content

Default design

smac.initial_design.default_design #

DefaultInitialDesign #

DefaultInitialDesign(
    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,
)

Bases: AbstractInitialDesign

Initial design that evaluates only the default configuration.

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}."
        )

meta property #

meta: dict[str, Any]

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