Skip to content

Forbidden relations of conditioned hyperparameters #1161

Closed
@bbudescu

Description

@bbudescu

Description

Using a relational constraint on the values that can be taken by two hyperparameters, one of them not being guaranteed to be sampled every time, causes a crash either when adding HPs to the config space, or when instantiating the Facade and sampling the initial configs.

Steps/Code to Reproduce

from ConfigSpace import (ConfigurationSpace, Configuration, Categorical, EqualsCondition, ForbiddenEqualsRelation,
                         ForbiddenAndConjunction, ForbiddenEqualsClause)
from smac import Scenario, HyperparameterOptimizationFacade, MultiFidelityFacade

a = Categorical('a', [2, 5, 10], ordered=True)
enable_a = Categorical('enable_a', [False, True])
cond_a = EqualsCondition(a, enable_a, True)

b = Categorical('b', [5, 10, 15], ordered=True)
forbid_a_b = ForbiddenEqualsRelation(a, b)
# forbid_a = ForbiddenEqualsClause(enable_a, True)
# forbid_a_b = ForbiddenAndConjunction(forbid_a, forbid_a_b)

cs = ConfigurationSpace()
cs.add([a, enable_a, cond_a, b, forbid_a_b])

scenario = Scenario(cs, deterministic=True, n_trials=200)

def train(config: Configuration, seed: int = 0, budget: int = 0) -> float:
    pass

smac = MultiFidelityFacade(scenario, train)

I've found that enabling the extra forbidden clause forbid_a in the commented line above, and replacing the original forbid_a_b by a ForbiddenAndConjunction helps when using HyperparameterOptimizationFacade but not with MultiFidelityFacade

Expected Results

No crash.

Actual Results

File "playground/playground_smac_bug.py", line 32, in <module>
    cs.add([a, enable_a, cond_a, b, forbid_a_b])
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/configuration_space.py", line 351, in add
    self._check_default_configuration()
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/configuration_space.py", line 915, in _check_default_configuration
    return Configuration(self, values=values)
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/configuration.py", line 126, in __init__
    self.check_valid_configuration()
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/configuration.py", line 160, in check_valid_configuration
    check_configuration(
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/util.py", line 611, in check_configuration
    if forbidden.is_forbidden_vector(vector):
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/forbidden.py", line 683, in is_forbidden_vector
    return self.left.to_value(left) == self.right.to_value(right)  # type: ignore
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/hyperparameters/hyperparameter.py", line 358, in to_value
    value: DType = self._transformer.to_value(np.array([vector]))[0]
  File "/home/bogdan/anaconda3/envs/smac/lib/python3.10/site-packages/ConfigSpace/hyperparameters/hp_components.py", line 174, in to_value
    raise ValueError(
ValueError: Got unexpected float value while trying to transform a vector representation into a value in [ 2  5 10].Expected integers but got [nan] (dtype: float64)

Versions

2.2.0

LE: setting default=True on init of enable_a helps avoid the issue happening at ConfigurationSpace.add() when checking the default configuration, and postpones it until a bunch of configs are sampled as vectors for the initial design (during the Facade initialization), where nans cause issues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions