Source code for smac.intensifier.hyperband_utils

from __future__ import annotations

import numpy as np

from smac.intensifier.successive_halving import SuccessiveHalving


[docs] def determine_HB(min_budget: float, max_budget: float, eta: int = 3) -> dict: """Determine one Hyperband round Parameters ---------- min_budget : float Minimum budget per trial in fidelity units max_budget : float Maximum budget per trial in fidelity units eta : int, defaults to 3 Input that controls the proportion of configurations discarded in each round of Successive Halving. Returns ------- dict Info about the Hyperband round "max_iterations" "n_configs_in_stage" "budgets_in_stage" "trials_used" "budget_used" "number_of_brackets" """ _s_max = SuccessiveHalving._get_max_iterations(eta, max_budget, min_budget) _max_iterations: dict[int, int] = {} _n_configs_in_stage: dict[int, list] = {} _budgets_in_stage: dict[int, list] = {} for i in range(_s_max + 1): max_iter = _s_max - i _budgets_in_stage[i], _n_configs_in_stage[i] = SuccessiveHalving._compute_configs_and_budgets_for_stages( eta, max_budget, max_iter, _s_max ) _max_iterations[i] = max_iter + 1 total_trials = np.sum([np.sum(v) for v in _n_configs_in_stage.values()]) total_budget = np.sum([np.sum(v) for v in _budgets_in_stage.values()]) return { "max_iterations": _max_iterations, "n_configs_in_stage": _n_configs_in_stage, "budgets_in_stage": _budgets_in_stage, "trials_used": total_trials, "budget_used": total_budget, "number_of_brackets": _s_max, }
[docs] def determine_hyperband_for_multifidelity( total_budget: float, min_budget: float, max_budget: float, eta: int = 3 ) -> dict: """Determine how many Hyperband rounds should happen based on a total budget Parameters ---------- total_budget : float Total budget for the complete optimization in fidelity units min_budget : float Minimum budget per trial in fidelity units max_budget : float Maximum budget per trial in fidelity units eta : int, defaults to 3 Input that controls the proportion of configurations discarded in each round of Successive Halving. Returns ------- dict Info about the Hyperband round "max_iterations" "n_configs_in_stage" "budgets_in_stage" "trials_used" "budget_used" "number_of_brackets" """ # Determine the HB hyperband_round = determine_HB(eta=eta, min_budget=min_budget, max_budget=max_budget) # Calculate how many HB rounds we can have budget_used_per_hyperband_round = hyperband_round["budget_used"] number_of_full_hb_rounds = int(np.floor(total_budget / budget_used_per_hyperband_round)) remaining_budget = total_budget % budget_used_per_hyperband_round trials_used_per_hb_round = hyperband_round["trials_used"] n_configs_in_stage = hyperband_round["n_configs_in_stage"] budgets_in_stage = hyperband_round["budgets_in_stage"] remaining_trials = 0 for stage in n_configs_in_stage.keys(): B = budgets_in_stage[stage] C = n_configs_in_stage[stage] for b, c in zip(B, C): # How many trials are left? # If b * c is lower than remaining budget, we can add full c # otherwise we need to find out how many trials we can do with this budget remaining_trials += min(c, int(np.floor(remaining_budget / b))) # We cannot go lower than 0 # If we are in the case of b*c > remaining_budget, we will not have any # budget left. We can not add full c but the number of trials that still fit remaining_budget = max(0, remaining_budget - b * c) # print(stage, b, c) # print("-"*20, remaining_trials, remaining_budget) n_trials = int(number_of_full_hb_rounds * trials_used_per_hb_round + remaining_trials) hyperband_info = hyperband_round hyperband_info["n_trials"] = n_trials hyperband_info["total_budget"] = total_budget hyperband_info["eta"] = eta hyperband_info["min_budget"] = min_budget hyperband_info["max_budget"] = max_budget return hyperband_info
[docs] def get_n_trials_for_hyperband_multifidelity( total_budget: float, min_budget: float, max_budget: float, eta: int = 3, print_summary: bool = True ) -> int: """Caculate the number of trials needed for multi-fidelity optimization Specify the total budget and find out how many trials that equals. Parameters ---------- total_budget : float Total budget for the complete optimization in fidelity units min_budget : float Minimum budget per trial in fidelity units max_budget : float Maximum budget per trial in fidelity units eta : int, defaults to 3 Input that controls the proportion of configurations discarded in each round of Successive Halving. Returns ------- int Number of trials needed for the specified total budgets """ hyperband_info = determine_hyperband_for_multifidelity( total_budget=total_budget, eta=eta, min_budget=min_budget, max_budget=max_budget ) if print_summary: print_hyperband_summary(hyperband_info=hyperband_info) return hyperband_info["n_trials"]