automl / SMAC3

SMAC3: A Versatile Bayesian Optimization Package for Hyperparameter Optimization
https://automl.github.io/SMAC3/v2.1.0/
Other
1.06k stars 219 forks source link

Hydra facade not working #889

Open marti-mcfly opened 1 year ago

marti-mcfly commented 1 year ago

Description

I am trying to use the hydra facade in smac/facade/experimental, however, it gives an error.

Steps/Code to Reproduce

def dnnv_from_cfg(cfg, seed, instance):

    #TAE function

    return score

if __name__ == "__main__":

    cs = ConfigurationSpace({

        })

    scenario = Scenario(
        {
            "run_obj": "quality", 
            "cutoff_time": 300,
            "ta_run_limit": 300,
            "wallclock_limit": 3600,
            "cs": cs,
            "deterministic": True,
            "train_inst_fn": 'instances.txt'
        }
    )

    # smac = SMAC4AC(
    #     scenario=scenario,
    #     tae_runner=dnnv_from_cfg
    # )

    # incumbent = smac.optimize()

    hydra = Hydra(scenario=scenario, n_iterations=2, tae=dnnv_from_cfg)
    hydra.optimize()

Expected Results

Hydra starts the configuration procedure.

Actual Results

INFO:smac.utils.io.cmd_reader.CMDReader:Output to smac3-output_2022-11-09_11:39:05_493000
Optimizing! Depending on your machine, this might take a few minutes.
INFO:smac.facade.smac_ac_facade.SMAC4AC:Optimizing a deterministic scenario for quality without a tuner timeout - will make SMAC deterministic and only evaluate one configuration per iteration!
INFO:smac.scenario.scenario.Scenario:No output directory for scenario logging specified -- scenario will not be logged.
INFO:smac.utils.io.traj_logging.TrajLogger:No output directory for trajectory logging specified -- trajectory will not be logged.
INFO:smac.initial_design.default_configuration_design.DefaultConfiguration:Running initial design for 1 configurations
INFO:smac.facade.experimental.hydra_facade.Hydra:========================================================================================================================
INFO:smac.facade.experimental.hydra_facade.Hydra:Hydra Iteration: 1
INFO:smac.facade.psmac_facade.PSMAC:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO:smac.facade.psmac_facade.PSMAC:PSMAC run
Traceback (most recent call last):
  File "run_dnnv.py", line 104, in <module>
    hydra.optimize()
  File "/.dnnv-env/lib/python3.7/site-packages/smac/facade/experimental/hydra_facade.py", line 214, in optimize
    incs = self.optimizer.optimize()
  File "/.dnnv-env/lib/python3.7/site-packages/smac/facade/psmac_facade.py", line 218, in optimize
    for seed in self.seeds
  File "/.dnnv-env/lib/python3.7/site-packages/joblib/parallel.py", line 1098, in __call__
    self.retrieve()
  File "/.dnnv-env/lib/python3.7/site-packages/joblib/parallel.py", line 975, in retrieve
    self._output.extend(job.get(timeout=self.timeout))
  File "/.dnnv-env/lib/python3.7/site-packages/joblib/_parallel_backends.py", line 567, in wrap_future_result
    return future.result(timeout=timeout)
  File "/anaconda3/lib/python3.7/concurrent/futures/_base.py", line 432, in result
    return self.__get_result()
  File "/anaconda3/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
TypeError: __init__() got an unexpected keyword argument 'tae'

Versions

smac 1.4.0

benjamc commented 1 year ago

Could you provide a full working example? :)

marti-mcfly commented 1 year ago

Yes, of course! This should work (and reproduce the error).

import logging

logging.basicConfig(level=logging.INFO)

import numpy as np
from ConfigSpace.conditions import InCondition
from ConfigSpace.hyperparameters import (
    CategoricalHyperparameter,
    UniformFloatHyperparameter,
    UniformIntegerHyperparameter,
)
from sklearn import datasets, svm
from sklearn.model_selection import cross_val_score

from smac.configspace import ConfigurationSpace
from smac.facade.smac_hpo_facade import SMAC4HPO
from smac.scenario.scenario import Scenario

from smac.facade.experimental.hydra_facade import Hydra

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

# We load the iris-dataset (a widely used benchmark)
iris = datasets.load_iris()

def svm_from_cfg(cfg):
    """Creates a SVM based on a configuration and evaluates it on the
    iris-dataset using cross-validation. Note here random seed is fixed
    Parameters:
    -----------
    cfg: Configuration (ConfigSpace.ConfigurationSpace.Configuration)
        Configuration containing the parameters.
        Configurations are indexable!
    Returns:
    --------
    A crossvalidated mean score for the svm on the loaded data-set.
    """
    # For deactivated parameters, the configuration stores None-values.
    # This is not accepted by the SVM, so we remove them.
    cfg = {k: cfg[k] for k in cfg if cfg[k]}
    # And for gamma, we set it to a fixed value or to "auto" (if used)
    if "gamma" in cfg:
        cfg["gamma"] = cfg["gamma_value"] if cfg["gamma"] == "value" else "auto"
        cfg.pop("gamma_value", None)  # Remove "gamma_value"

    clf = svm.SVC(**cfg, random_state=42)

    scores = cross_val_score(clf, iris.data, iris.target, cv=5)
    return 1 - np.mean(scores)  # Minimize!

if __name__ == "__main__":
    # Build Configuration Space which defines all parameters and their ranges
    cs = ConfigurationSpace()

    # We define a few possible types of SVM-kernels and add them as "kernel" to our cs
    kernel = CategoricalHyperparameter("kernel", ["linear", "rbf", "poly", "sigmoid"], default_value="poly")
    cs.add_hyperparameter(kernel)

    # There are some hyperparameters shared by all kernels
    C = UniformFloatHyperparameter("C", 0.001, 1000.0, default_value=1.0, log=True)
    shrinking = CategoricalHyperparameter("shrinking", [True, False], default_value=True)
    cs.add_hyperparameters([C, shrinking])

    # Others are kernel-specific, so we can add conditions to limit the searchspace
    degree = UniformIntegerHyperparameter("degree", 1, 5, default_value=3)  # Only used by kernel poly
    coef0 = UniformFloatHyperparameter("coef0", 0.0, 10.0, default_value=0.0)  # poly, sigmoid
    cs.add_hyperparameters([degree, coef0])

    use_degree = InCondition(child=degree, parent=kernel, values=["poly"])
    use_coef0 = InCondition(child=coef0, parent=kernel, values=["poly", "sigmoid"])
    cs.add_conditions([use_degree, use_coef0])

    # This also works for parameters that are a mix of categorical and values
    # from a range of numbers
    # For example, gamma can be either "auto" or a fixed float
    gamma = CategoricalHyperparameter("gamma", ["auto", "value"], default_value="auto")  # only rbf, poly, sigmoid
    gamma_value = UniformFloatHyperparameter("gamma_value", 0.0001, 8, default_value=1, log=True)
    cs.add_hyperparameters([gamma, gamma_value])
    # We only activate gamma_value if gamma is set to "value"
    cs.add_condition(InCondition(child=gamma_value, parent=gamma, values=["value"]))
    # And again we can restrict the use of gamma in general to the choice of the kernel
    cs.add_condition(InCondition(child=gamma, parent=kernel, values=["rbf", "poly", "sigmoid"]))

    # Scenario object
    scenario = Scenario(
        {
            "run_obj": "quality",  # we optimize quality (alternatively runtime)
            "runcount-limit": 50,  # max. number of function evaluations
            "cs": cs,  # configuration space
            "deterministic": True,
        }
    )

    # Example call of the function
    # It returns: Status, Cost, Runtime, Additional Infos
    def_value = svm_from_cfg(cs.get_default_configuration())
    print("Default Value: %.2f" % (def_value))

    # Optimize, using a SMAC-object
    # print("Optimizing! Depending on your machine, this might take a few minutes.")
    # smac = SMAC4HPO(scenario=scenario, rng=np.random.RandomState(42), tae_runner=svm_from_cfg)

    # incumbent = smac.optimize()

    hydra = Hydra(scenario=scenario, n_iterations=2)
    hydra.optimize()
benjamc commented 1 year ago

I started fixing it on branch fix_#889

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

benjamc commented 1 year ago

from #909 :

v2.0.0 [HydraFacade] We need to validate configs on a user-defined test (instance) set.

When SMAC returns an incumbent configuration after calling smac.optimize, how do I validate the cost of this configuration per instance of the dataset? The docstring of the validate method of the AbstractFacade (same for SMBO) describes a parameter for selecting specific instances, but this parameter is not actually implemented.