Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Problem with HyperBand setup given a total budget #1179

Open
becktepe opened this issue Dec 6, 2024 · 1 comment
Open

[BUG] Problem with HyperBand setup given a total budget #1179

becktepe opened this issue Dec 6, 2024 · 1 comment
Labels
Milestone

Comments

@becktepe
Copy link

becktepe commented Dec 6, 2024

Description

I wanted to use HyperBand and define a total budget as shown in the documentation. However, the actual budget that is used by SMAC does not match the requested budget.

The bug is caused by this line:

total_budget = np.sum([np.sum(v) for v in _budgets_in_stage.values()])

When computing the total budget of a HyperBand bracket we need to multiply the number of configs per budget by the respective budget:

  total_budget = 0
  for stage in _n_configs_in_stage.keys():
      for b, c in zip(_budgets_in_stage[stage], _n_configs_in_stage[stage]):
          total_budget += b * c

After fixing this, the actual budget is 9_999.99.

Steps/Code to Reproduce

This is basically the example mentioned above:

from __future__ import annotations

import numpy as np
from ConfigSpace import Configuration, ConfigurationSpace, Float
from matplotlib import pyplot as plt

from smac import MultiFidelityFacade, RunHistory, Scenario
from smac.intensifier.hyperband_utils import get_n_trials_for_hyperband_multifidelity

__copyright__ = "Copyright 2021, AutoML.org Freiburg-Hannover"
__license__ = "3-clause BSD"


class QuadraticFunction:
    max_budget = 500

    @property
    def configspace(self) -> ConfigurationSpace:
        cs = ConfigurationSpace(seed=0)
        x = Float("x", (-5, 5), default=-5)
        cs.add([x])

        return cs

    def train(self, config: Configuration, seed: int = 0, budget: float | None = None) -> float:
        """Returns the y value of a quadratic function with a minimum we know to be at x=0."""
        x = config["x"]

        if budget is None:
            multiplier = 1
        else:
            multiplier = 1 + budget / self.max_budget

        return x**2 * multiplier


if __name__ == "__main__":
    model = QuadraticFunction()

    total_budget = 10000
    min_budget = 10  # minimum budget per trial
    max_budget = 500  # maximum budget per trial
    eta = 3  # standard HB parameter influencing the number of stages

    # Let's calculate how many trials we need to exhaust the total optimization budget (in terms of
    # fidelity units)
    n_trials = get_n_trials_for_hyperband_multifidelity(
        total_budget=total_budget,  # this is the total optimization budget we specify in terms of fidelity units
        min_budget=min_budget,  # This influences the Hyperband rounds, minimum budget per trial
        max_budget=max_budget,  # This influences the Hyperband rounds, maximum budget per trial
        eta=eta,  # This influences the Hyperband rounds
        print_summary=True,
    )

    # Scenario object specifying the optimization "environment"
    scenario = Scenario(
        model.configspace, deterministic=True, n_trials=n_trials, min_budget=min_budget, max_budget=max_budget
    )

    # Now we use SMAC to find the best hyperparameters
    smac = MultiFidelityFacade(
        scenario,
        model.train,  # We pass the target function here
        overwrite=True,  # Overrides any previous results that are found that are inconsistent with the meta-data
        intensifier=MultiFidelityFacade.get_intensifier(scenario=scenario, eta=eta),
    )

    incumbent = smac.optimize()

    total_budget_used = sum([trial.budget for trial in smac.runhistory])

    print(f"Total budget defined: {total_budget}")
    print(f"Total budget used: {total_budget_used}")

Expected Results

After calling get_n_trials_for_hyperband_multifidelity with a total budget of 10_000 I would expect the actual used budget to be less than or equal to 10_000.

Actual Results

The actual used budget is 25_611.11.

Versions

2.2.0

@becktepe becktepe changed the title [BUG] [BUG] Problem with HyperBand setup given a total budget Dec 6, 2024
@benjamc benjamc added the bug label Dec 19, 2024
@benjamc
Copy link
Collaborator

benjamc commented Dec 19, 2024

Hi @becktepe
just to confirm, the fix is this?

total_budget = 0
for stage in _n_configs_in_stage.keys():
    for b, c in zip(_budgets_in_stage[stage], _n_configs_in_stage[stage]):
        total_budget += b * c

@benjamc benjamc added this to the v2.3 milestone Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

2 participants