Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
becktepe authored Oct 8, 2024
2 parents c5c7bfe + b4e00e8 commit 4094500
Show file tree
Hide file tree
Showing 21 changed files with 113 additions and 179 deletions.
15 changes: 7 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ clean-build: ## remove build artifacts
rm -fr dist/
rm -fr .eggs/
find . -name '*.egg-info' -exec rm -fr {} +
find . -name '*.egg' -exec rm -f {} +

clean-pyc: ## remove Python file artifacts
find . -name '*.pyc' -exec rm -f {} +
Expand All @@ -51,11 +50,11 @@ clean-docs: ## remove docs artifacts
cd docs && make clean

ruff: ## run ruff as a formatter
python -m ruff format hydra_plugins
python -m ruff check --silent --exit-zero --no-cache --fix hydra_plugins
python -m ruff check --exit-zero hydra_plugins
uvx ruff format hydra_plugins
uvx ruff check --silent --exit-zero --no-cache --fix hydra_plugins
uvx ruff check --exit-zero hydra_plugins
isort:
python -m isort hydra_plugins tests
uvx isort hydra_plugins tests

test: ## run tests quickly with the default Python
python -m pytest tests
Expand Down Expand Up @@ -99,13 +98,13 @@ dist: clean ## builds source and wheel package
python setup.py bdist_wheel
ls -l dist
install: clean ## install the package to the active Python's site-packages
pip install -e . --config-settings editable_mode=compat
uv pip install -e . --config-settings editable_mode=compat

install-dev: clean ## install the package to the active Python's site-packages
pip install -e ".[dev,examples,doc,all]" --config-settings editable_mode=compat
uv pip install -e ".[dev,examples,doc,all]" --config-settings editable_mode=compat

check:
pre-commit run --all-files
uvx pre-commit run --all-files

format:
make ruff
Expand Down
13 changes: 3 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,15 @@ We recommend installing hypersweeper via a uv virtual environment:

```bash
pip install uv
uv init
uv sync
uv venv --python 3.10
make install
```

For extra dependencies, add them to the sync command like this:
For extra dependencies, add them like this:
```bash
uv sync --extra dev --extra carps
```

Alternatively you can also install in a fresh conda environment:

```bash
conda create -n hypersweeper python=3.10
make install
```

## Basic Usage

To use the sweeper, you need to specify a target function with a hydra interface (see our examples).
Expand Down
4 changes: 2 additions & 2 deletions examples/configs/branin_carps_hebo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ hydra:
task: ${carps_task}
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_carps_hebo/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_carps_hebo/
4 changes: 2 additions & 2 deletions examples/configs/branin_carps_smac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ hydra:
_partial_: true
eta: 3
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_carps_smac/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_carps_smac/
4 changes: 2 additions & 2 deletions examples/configs/branin_nevergrad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ hydra:
budget: 100
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_nevergrad/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_nevergrad/
4 changes: 2 additions & 2 deletions examples/configs/branin_rs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ hydra:
max_budget: 100
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_rs/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_rs/
4 changes: 2 additions & 2 deletions examples/configs/branin_smac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ hydra:
output_directory: ${hydra.sweep.dir}
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_smac/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/branin_smac/
4 changes: 2 additions & 2 deletions examples/configs/mlp_carps_smac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ hydra:
eta: 3
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_carps_smac/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_carps_smac/
4 changes: 2 additions & 2 deletions examples/configs/mlp_dehb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ hydra:
output_path: ${hydra.sweep.dir}
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_dehb/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_dehb/
4 changes: 2 additions & 2 deletions examples/configs/mlp_hebo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ hydra:
n_trials: 10
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_hebo/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_hebo/
4 changes: 2 additions & 2 deletions examples/configs/mlp_smac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ hydra:
output_directory: ${hydra.sweep.dir}
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_smac/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/mlp_smac/
4 changes: 2 additions & 2 deletions examples/configs/sac_pb2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ hydra:
load_tf: true
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/sac_pb2/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/sac_pb2/
4 changes: 2 additions & 2 deletions examples/configs/sac_pbt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ hydra:
load_tf: true
search_space: ${search_space}
run:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/sac_pbt/
sweep:
dir: ./tmp/${now:%Y-%m-%d}/${now:%H-%M-%S}
dir: ./tmp/sac_pbt/
61 changes: 30 additions & 31 deletions hydra_plugins/hyper_pbt/bg_pbt_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""All of this is copied/lightly adapted from the original BG-PBT code: https://github.com/xingchenwan/bgpbt."""

from __future__ import annotations

import logging
Expand Down Expand Up @@ -122,8 +123,8 @@ def get_start_point(cs: CS.ConfigurationSpace, x_center, frozen_dims: list[int]
# print(param_name)
if np.isnan(new_config_array[i]) or (frozen_dims is not None and i in frozen_dims):
continue
param_name = cs.get_hyperparameter_by_idx(i)
if type(cs[param_name]) == CSH.CategoricalHyperparameter:
param_name = cs.at(i)
if isinstance(cs[param_name], CSH.CategoricalHyperparameter):
new_config_array[i] = rng.choice(range(len(cs[param_name].choices)))
elif (
type(cs[param_name]) in [CSH.UniformIntegerHyperparameter, CSH.NormalIntegerHyperparameter]
Expand All @@ -139,9 +140,9 @@ def get_start_point(cs: CS.ConfigurationSpace, x_center, frozen_dims: list[int]
config = deactivate_inactive_hyperparameters(config, cs)

try:
cs.check_configuration(config)
config.check_valid_configuration()
except ValueError:
config = CS.Configuration(cs, config.get_dictionary())
config = CS.Configuration(cs, dict(config))
new_config_array = config.get_array()
if return_config:
return new_config_array, config
Expand All @@ -167,23 +168,23 @@ def construct_bounding_box(
weights = weights / np.prod(np.power(weights, 1.0 / len(weights)))
lb, ub = np.zeros_like(x), np.ones_like(x)
for i, _dim in enumerate(x):
if np.isnan(x[i]) or i >= len(cs):
if np.isnan(_dim) or i >= len(cs):
lb[i], ub[i] = 0.0, 1.0
else:
hp = cs[cs.get_hyperparameter_by_idx(i)]
if type(hp) == CSH.CategoricalHyperparameter:
hp = cs[cs.at(i)]
if isinstance(hp, CSH.CategoricalHyperparameter):
lb[i], ub[i] = 0, len(hp.choices)
else:
lb[i] = np.clip(x[i] - weights[i] * tr_length / 2.0, 0.0, 1.0)
ub[i] = np.clip(x[i] + weights[i] * tr_length / 2.0, 0.0, 1.0)
if type(hp) in [
CSH.UniformIntegerHyperparameter,
CSH.NormalIntegerHyperparameter,
CSH.NormalFloatHyperparameter,
CSH.UniformFloatHyperparameter,
lb[i] = np.clip(_dim - weights[i] * tr_length / 2.0, 0.0, 1.0)
ub[i] = np.clip(_dim + weights[i] * tr_length / 2.0, 0.0, 1.0)
if any[
isinstance(hp, CSH.UniformIntegerHyperparameter),
isinstance(hp, CSH.NormalIntegerHyperparameter),
isinstance(hp, CSH.NormalFloatHyperparameter),
isinstance(hp, CSH.UniformFloatHyperparameter),
]:
lb[i] = max(hp._inverse_transform(hp.lower), lb[i])
ub[i] = min(hp._inverse_transform(hp.upper), ub[i])
lb[i] = max(hp.to_vector(hp.lower), lb[i])
ub[i] = min(hp.to_vector(hp.upper), ub[i])
return lb, ub


Expand All @@ -199,20 +200,20 @@ def get_dim_info(cs: CS.ConfigurationSpace, x, return_indices=False):
# do not sample an inactivated hyperparameter (such a hyperparameter has nan value imputed)
if x[variable] != x[variable]:
continue
if type(cs[cs.get_hyperparameter_by_idx(variable)]) == CSH.CategoricalHyperparameter:
cat_dims.append(cs.get_hyperparameter_by_idx(variable))
if isinstance(cs[cs.at(variable)], CSH.CategoricalHyperparameter):
cat_dims.append(cs.at(variable))
cat_dims_idx.append(i)
elif type(cs[cs.get_hyperparameter_by_idx(variable)]) in [
elif type(cs[cs.at(variable)]) in [
CSH.UniformIntegerHyperparameter,
CSH.NormalIntegerHyperparameter,
]:
int_dims.append(cs.get_hyperparameter_by_idx(variable))
int_dims.append(cs.at(variable))
int_dims_idx.append(i)
elif type(cs[cs.get_hyperparameter_by_idx(variable)]) in [
elif type(cs[cs.at(variable)]) in [
CSH.UniformFloatHyperparameter,
CSH.NormalFloatHyperparameter,
]:
cont_dims.append(cs.get_hyperparameter_by_idx(variable))
cont_dims.append(cs.at(variable))
cont_dims_idx.append(i)
if return_indices:
return cat_dims_idx, cont_dims_idx, int_dims_idx
Expand All @@ -238,21 +239,21 @@ def sample_discrete_neighbour(cs: CS.ConfigurationSpace, x, frozen_dims: list[in
config = CS.Configuration(cs, vector=x.detach().numpy() if isinstance(x, torch.Tensor) else x)

try:
cs.check_configuration(config)
config.check_valid_configuration()
except ValueError:
# there seems to be a bug with ConfigSpace that raises error even when a config is valid
# Issue #196: https://github.com/automl/ConfigSpace/issues/196
# print(config)
config = CS.Configuration(cs, config.get_dictionary())
config = CS.Configuration(cs, dict(config))

# print(config)
config_pert = deepcopy(config)
rng = np.random.default_rng()
selected_dim = str(rng.choice(cat_dims + int_dims, 1)[0])
index_in_array = cs.get_idx_by_hyperparameter_name(selected_dim)
index_in_array = cs.index_of(selected_dim)
while config_pert[selected_dim] is None or (frozen_dims is not None and index_in_array in frozen_dims):
selected_dim = str(rng.choice(cat_dims + int_dims, 1)[0])
index_in_array = cs.get_idx_by_hyperparameter_name(selected_dim)
index_in_array = cs.index_of(selected_dim)

# if the selected dimension is categorical, change the value to another variable
if selected_dim in cat_dims:
Expand Down Expand Up @@ -629,12 +630,10 @@ def __init__(
# extract the dim indices of the continuous dimensions (incl. integers)
self.cont_dims = [
i
for i, dim in enumerate(self.cs.get_hyperparameters())
for i, dim in enumerate(self.cs.values())
if type(dim) in [CSH.UniformIntegerHyperparameter, CSH.UniformFloatHyperparameter]
]
self.cat_dims = [
i for i, dim in enumerate(self.cs.get_hyperparameters()) if type(dim) == CSH.CategoricalHyperparameter
]
self.cat_dims = [i for i, dim in enumerate(self.cs.values()) if isinstance(dim, CSH.CategoricalHyperparameter)]

# initialise the kernels
self.continuous_kern = ConditionalMatern(
Expand Down Expand Up @@ -794,7 +793,7 @@ def rbf(d, ard):
if exp == "rbf":
k_cat = rbf(diff1, self.ard_num_dims is not None and self.ard_num_dims > 1)
else:
raise ValueError("Exponentiation scheme %s is not recognised!" % exp)
raise ValueError(f"Exponentiation scheme {exp} is not recognised!")
if diag:
return torch.diag(k_cat).float()
return k_cat.float()
Expand Down
11 changes: 4 additions & 7 deletions hydra_plugins/hyper_pbt/pb2_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ def __init__(self, input_dim, variance=1.0, lengthscale=1.0, epsilon=0.0, active
def K(self, X, X2):
"""Compute the kernel."""
# time must be in the far left column
if self.epsilon > 0.5: # noqa: PLR2004
self.epsilon = 0.5
self.epsilon = min(self.epsilon, 0.5)
if X2 is None:
X2 = np.copy(X)
T1 = X[:, 0].reshape(-1, 1)
Expand Down Expand Up @@ -188,11 +187,9 @@ def K2(self, x, x2):
def K(self, x, x2):
"""Compute the kernel."""
# clip epsilons
if self.epsilon_1 > 0.5: # noqa: PLR2004
self.epsilon_1 = 0.5
self.epsilon_1 = min(self.epsilon_1, 0.5)

if self.epsilon_2 > 0.5: # noqa: PLR2004
self.epsilon_2 = 0.5
self.epsilon_2 = min(self.epsilon_2, 0.5)

# format data
if x2 is None:
Expand Down Expand Up @@ -538,7 +535,7 @@ def exp3_get_cat(row, data, num_rounds, index):
sum_w = np.sum(weights)
weights = [w / sum_w for w in weights]

count += 1
count += 1 # noqa: SIM113

# now we select our arm!

Expand Down
3 changes: 0 additions & 3 deletions hydra_plugins/hypersweeper/hypersweeper_sweeper.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,6 @@ def run_configs(self, infos):
for j in range(len(overrides)):
performances.append(res[j].return_value)
self.trials_run += 1
if self.maximize:
performances = [-p for p in performances]
return performances, costs

def get_save_path(self, config_id, seed=None):
Expand Down Expand Up @@ -471,7 +469,6 @@ def run(self, verbose=False):
performance = float(np.mean(performance))

logged_performance = -performance if self.maximize else performance

value = Result(performance=logged_performance, cost=cost)
self.optimizer.tell(info=info, value=value)

Expand Down
Loading

0 comments on commit 4094500

Please sign in to comment.