Skip to content

Mf bo

neps.optimizers.multi_fidelity.mf_bo #

MFBOBase #

Designed to work with model-based search on SH-based multi-fidelity algorithms.

Requires certain strict assumptions about fidelities and rung maps.

is_init_phase #

is_init_phase() -> bool

Returns True is in the warmstart phase and False under model-based search.

Source code in neps/optimizers/multi_fidelity/mf_bo.py
def is_init_phase(self) -> bool:
    """Returns True is in the warmstart phase and False under model-based search."""
    if self.modelling_type == "rung":
        # build a model per rung or per fidelity
        # in this case, the initial design checks if `init_size` number of
        # configurations have finished at a rung or not and the highest such rung is
        # chosen for model building at teh current iteration
        if self._active_rung() is None:
            return True
    elif self.modelling_type == "joint":
        # builds a model across all fidelities with the fidelity as a dimension
        # in this case, calculate the total number of function evaluations spent
        # and in vanilla BO fashion use that to compare with the initital design size
        valid_perf_mask = self.observed_configs["perf"].notna()
        rungs = self.observed_configs.loc[valid_perf_mask, "rung"]
        total_resources = sum(self.rung_map[r] for r in rungs)
        resources = total_resources / self.max_budget
        if resources < self.init_size:
            return True
    else:
        raise ValueError("Choice of modelling_type not in {{'rung', 'joint'}}")
    return False

sample_new_config #

sample_new_config(
    rung: int | None = None, **kwargs: Any
) -> SearchSpace

Samples configuration from policies or random.

Source code in neps/optimizers/multi_fidelity/mf_bo.py
def sample_new_config(
    self,
    rung: int | None = None,
    **kwargs: Any,
) -> SearchSpace:
    """Samples configuration from policies or random."""
    if self.model_based and not self.is_init_phase():
        incumbent = None
        if self.modelling_type == "rung":
            # `rung` should not be None when not in init phase
            active_max_rung = self._active_rung()
            fidelity = None
            active_max_fidelity = self.rung_map[active_max_rung]
        elif self.modelling_type == "joint":
            fidelity = self.rung_map[rung]
            active_max_fidelity = None
            # IMPORTANT step for correct 2-step acquisition
            incumbent = min(self.rung_histories[rung]["perf"])
        else:
            raise ValueError("Choice of modelling_type not in 'rung', 'joint'")
        assert (
            (fidelity is None and active_max_fidelity is not None)
            or (active_max_fidelity is None and fidelity is not None)
            or (active_max_fidelity is not None and fidelity is not None)
        ), "Either condition needs to be not None!"
        config = self.model_policy.sample(
            active_max_fidelity=active_max_fidelity,
            fidelity=fidelity,
            incumbent=incumbent,
            **self.sampling_args,
        )
    elif self.sampling_policy is not None:
        config = self.sampling_policy.sample(**self.sampling_args)
    else:
        config = sample_one_old(
            self.pipeline_space,
            patience=self.patience,
            user_priors=self.use_priors,
            ignore_fidelity=True,
        )
    return config