Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blackboxopt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "5.3.8"
__version__ = "6.0.0"

from parameterspace import ParameterSpace

Expand Down
22 changes: 13 additions & 9 deletions blackboxopt/optimizers/bohb.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
from parameterspace import ParameterSpace

from blackboxopt import Objective
from blackboxopt.optimizers.staged.utils import greedy_promotion

try:
from blackboxopt.optimizers.staged.bohb import Sampler as BOHBSampler
from blackboxopt.optimizers.staged.hyperband import create_hyperband_iteration
from blackboxopt.optimizers.staged.optimizer import StagedIterationOptimizer
from blackboxopt.optimizers.staged.optimizer import (
SingleObjectiveStagedIterationOptimizer,
)
except ImportError as e:
raise ImportError(
"Unable to import BOHB optimizer specific dependencies. "
+ "Make sure to install blackboxopt[bohb]"
) from e


class BOHB(StagedIterationOptimizer):
class BOHB(SingleObjectiveStagedIterationOptimizer):
def __init__(
self,
search_space: ParameterSpace,
Expand Down Expand Up @@ -124,11 +127,12 @@ def _create_new_iteration(self, iteration_index):
`blackboxopt.optimizer.utils.staged_iteration.StagedIteration` object
"""
return create_hyperband_iteration(
iteration_index,
self.min_fidelity,
self.max_fidelity,
self.eta,
self.config_sampler,
self.objective,
self.logger,
iteration_index=iteration_index,
min_fidelity=self.min_fidelity,
max_fidelity=self.max_fidelity,
eta=self.eta,
config_sampler=self.config_sampler,
objectives=[self.objective],
config_promotion_function=greedy_promotion,
logger=self.logger,
)
22 changes: 13 additions & 9 deletions blackboxopt/optimizers/hyperband.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@
from parameterspace import ParameterSpace

from blackboxopt import Objective
from blackboxopt.optimizers.staged.utils import greedy_promotion

try:
from blackboxopt.optimizers.staged.configuration_sampler import RandomSearchSampler
from blackboxopt.optimizers.staged.hyperband import create_hyperband_iteration
from blackboxopt.optimizers.staged.iteration import StagedIteration
from blackboxopt.optimizers.staged.optimizer import StagedIterationOptimizer
from blackboxopt.optimizers.staged.optimizer import (
SingleObjectiveStagedIterationOptimizer,
)
except ImportError as e:
raise ImportError(
"Unable to import Hyperband optimizer specific dependencies. "
+ "Make sure to install blackboxopt[hyperband]"
) from e


class Hyperband(StagedIterationOptimizer):
class Hyperband(SingleObjectiveStagedIterationOptimizer):
def __init__(
self,
search_space: ParameterSpace,
Expand Down Expand Up @@ -78,11 +81,12 @@ def _create_new_iteration(self, iteration_index: int) -> StagedIteration:
`blackboxopt.optimizer.staged.iteration.StagedIteration` object
"""
return create_hyperband_iteration(
iteration_index,
self.min_fidelity,
self.max_fidelity,
self.eta,
self.config_sampler,
self.objective,
self.logger,
iteration_index=iteration_index,
min_fidelity=self.min_fidelity,
max_fidelity=self.max_fidelity,
eta=self.eta,
config_sampler=self.config_sampler,
objectives=[self.objective],
config_promotion_function=greedy_promotion,
logger=self.logger,
)
140 changes: 140 additions & 0 deletions blackboxopt/optimizers/mobohb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Copyright (c) 2020 - for information on the respective copyright owner
# see the NOTICE file and/or the repository https://github.com/boschresearch/blackboxopt
#
# SPDX-License-Identifier: Apache-2.0

import logging
from typing import List, Optional

import numpy as np
from parameterspace import ParameterSpace

from blackboxopt import Objective

try:
from blackboxopt.optimizers.staged.hyperband import create_hyperband_iteration
from blackboxopt.optimizers.staged.iteration import Datum
from blackboxopt.optimizers.staged.mobohb import Sampler, argsort_nondominated
from blackboxopt.optimizers.staged.optimizer import (
MultiObjectiveStagedIterationOptimizer,
)
except ImportError as e:
raise ImportError(
"Unable to import MO-BOHB optimizer specific dependencies. "
+ "Make sure to install blackboxopt[mobohb]"
) from e


def _nondominated_promotion(data: List[Datum], num_configs: int) -> list:
"""Promote configurations to the next stage by multi-objective nondominated rank.

Args:
data: List with all successful evaluations for this stage. All failed
configurations have already been removed.
num_configs: Maximum number of configurations to be promoted.

Returns:
List of the config_keys to be evaluated on the next higher fidelity.
"""
if not data:
return []

losses = np.stack([d.losses for d in data])
n = min(num_configs, len(data))
selected = argsort_nondominated(losses)[:n]
return [data[i].config_key for i in selected]


class MOBOHB(MultiObjectiveStagedIterationOptimizer):
def __init__(
self,
search_space: ParameterSpace,
objectives: List[Objective],
min_fidelity: float,
max_fidelity: float,
num_iterations: int,
eta: float = 3.0,
top_n_percent: int = 15,
min_samples_in_model: Optional[int] = None,
num_samples: int = 64,
random_fraction: float = 1 / 3,
bandwidth_factor: float = 3.0,
min_bandwidth: float = 1e-3,
seed: Optional[int] = None,
logger: Optional[logging.Logger] = None,
):
"""Multi-objective BOHB Optimizer.

MO-BOHB extends BOHB to multiple objectives by replacing its single-objective,
scalar-loss based good/bad split with a multi-objective one: configurations are
ranked by nondominated (Pareto) front and, within the boundary front, by
crowding distance (NSGA-II style). The same ranking drives the successive
halving promotion between stages. The Bayesian optimization component (kernel
density estimators and expected improvement sampling) is reused from BOHB
unchanged.

Args:
search_space: [description]
objectives: The objectives of the optimization.
min_fidelity: The smallest fidelity value that is still meaningful.
Must be strictly greater than zero!
max_fidelity: The largest fidelity value used during the optimization.
Must not be smaller than `min_fidelity`.
num_iterations: The number of iterations that the optimizer will run.
eta: Scaling parameter to control the aggressiveness of Hyperband's racing.
top_n_percent: Determines the percentile of configurations that will be
used as training data for the kernel density estimator of the good
configurations, e.g. if set to 10 the best 10% configurations (by
nondominated rank) will be considered for training.
min_samples_in_model: Minimum number of datapoints needed to fit a model.
num_samples: Number of samples drawn to optimize EI via sampling.
random_fraction: Fraction of random configurations returned.
bandwidth_factor: Widens the bandwidth for contiuous parameters for
proposed points to optimize EI
min_bandwidth: to keep diversity, even when all (good) samples have the
same value for one of the parameters, a minimum bandwidth
(reasonable default: 1e-3) is used instead of zero.
seed: [description]
logger: [description]
"""
if min_samples_in_model is None:
min_samples_in_model = 3 * len(search_space)

self.min_fidelity = min_fidelity
self.max_fidelity = max_fidelity
self.eta = eta

self.config_sampler = Sampler(
search_space=search_space,
objectives=objectives,
min_samples_in_model=min_samples_in_model,
top_n_percent=top_n_percent,
num_samples=num_samples,
random_fraction=random_fraction,
bandwidth_factor=bandwidth_factor,
min_bandwidth=min_bandwidth,
seed=seed,
)

super().__init__(
search_space=search_space,
objectives=objectives,
num_iterations=num_iterations,
seed=seed,
logger=logger,
)

def _create_new_iteration(self, iteration_index):
"""Optimizer specific way to create a new
`blackboxopt.optimizer.utils.staged_iteration.StagedIteration` object
"""
return create_hyperband_iteration(
iteration_index=iteration_index,
min_fidelity=self.min_fidelity,
max_fidelity=self.max_fidelity,
eta=self.eta,
config_sampler=self.config_sampler,
objectives=self.objectives,
logger=self.logger,
config_promotion_function=_nondominated_promotion,
)
Loading
Loading