def setUp(self): x = RangeParameter("x", ParameterType.FLOAT, lower=0, upper=1) y = RangeParameter("y", ParameterType.FLOAT, lower=1, upper=2, is_fidelity=True) z = RangeParameter("z", ParameterType.FLOAT, lower=0, upper=5) self.parameters = [x, y, z] parameter_constraints = [ OrderConstraint(x, y), SumConstraint([x, z], False, 3.5), ] self.search_space = SearchSpace(self.parameters, parameter_constraints) self.observation_features = [ ObservationFeatures(parameters={ "x": 0.2, "y": 1.2, "z": 3 }), ObservationFeatures(parameters={ "x": 0.4, "y": 1.4, "z": 3 }), ObservationFeatures(parameters={ "x": 0.6, "y": 1.6, "z": 3 }), ] self.observation_data = [ ObservationData( metric_names=["a", "b"], means=np.array([1.0, -1.0]), covariance=np.array([[1.0, 4.0], [4.0, 6.0]]), ), ObservationData( metric_names=["a", "b"], means=np.array([2.0, -2.0]), covariance=np.array([[2.0, 5.0], [5.0, 7.0]]), ), ObservationData(metric_names=["a"], means=np.array([3.0]), covariance=np.array([[3.0]])), ] self.observations = [ Observation( features=self.observation_features[i], data=self.observation_data[i], arm_name=str(i), ) for i in range(3) ] self.pending_observations = { "b": [ObservationFeatures(parameters={ "x": 0.6, "y": 1.6, "z": 3 })] } self.model_gen_options = {"option": "yes"}
def constraint_from_str( representation: str, parameters: Dict[str, Parameter] ) -> ParameterConstraint: """Parse string representation of a parameter constraint.""" tokens = representation.split() parameter_names = parameters.keys() order_const = len(tokens) == 3 and tokens[1] in COMPARISON_OPS sum_const = ( len(tokens) >= 5 and len(tokens) % 2 == 1 and tokens[-2] in COMPARISON_OPS ) if not (order_const or sum_const): raise ValueError( "Parameter constraint should be of form <parameter_name> >= " "<other_parameter_name> for order constraints or `<parameter_name> " "+ <other_parameter_name> >= x, where any number of terms can be " "added and `x` is a float bound. Acceptable comparison operators " 'are ">=" and "<=".' ) if len(tokens) == 3: # Case "x1 >= x2" => order constraint. left, right = tokens[0], tokens[2] assert left in parameter_names, f"Parameter {left} not in {parameter_names}." assert right in parameter_names, f"Parameter {right} not in {parameter_names}." return ( OrderConstraint( lower_parameter=parameters[left], upper_parameter=parameters[right] ) if COMPARISON_OPS[tokens[1]] is ComparisonOp.LEQ else OrderConstraint( lower_parameter=parameters[right], upper_parameter=parameters[left] ) ) try: # Case "x1 - 2*x2 + x3 >= 2" => parameter constraint. bound = float(tokens[-1]) except ValueError: raise ValueError(f"Bound for the constraint must be a number; got {tokens[-1]}") if any(token[0] == "*" or token[-1] == "*" for token in tokens): raise ValueError( "A linear constraint should be the form a*x + b*y - c*z <= d" ", where a,b,c,d are float constants and x,y,z are parameters. " "There should be no space in each term around the operator * while " "there should be a single space around each operator +, -, <= and >=." ) parameter_weight = {} comparison_multiplier = ( 1.0 if COMPARISON_OPS[tokens[-2]] is ComparisonOp.LEQ else -1.0 ) operator_sign = 1.0 # Determines whether the operator is + or - for idx, token in enumerate(tokens[:-2]): if idx % 2 == 0: split_token = token.split("*") parameter = "" # Initializing the parameter multiplier = 1.0 # Initializing the multiplier if len(split_token) == 2: # There is a non-unit multiplier try: multiplier = float(split_token[0]) except ValueError: raise ValueError( f"Multiplier should be float; got {split_token[0]}" ) parameter = split_token[1] elif len(split_token) == 1: # The multiplier is either -1 or 1 parameter = split_token[0] if parameter[0] == "-": # The multiplier is -1 parameter = parameter[1:] multiplier = -1.0 else: multiplier = 1.0 assert ( parameter in parameter_names ), f"Parameter {parameter} not in {parameter_names}." parameter_weight[parameter] = operator_sign * multiplier else: assert ( token == "+" or token == "-" ), f"Expected a mixed constraint, found operator {token}." operator_sign = 1.0 if token == "+" else -1.0 return ParameterConstraint( constraint_dict={ p: comparison_multiplier * parameter_weight[p] for p in parameter_weight }, bound=comparison_multiplier * bound, )
def get_order_constraint() -> OrderConstraint: w = get_range_parameter() x = get_range_parameter2() return OrderConstraint(lower_parameter=x, upper_parameter=w)
parameter_type=ParameterType.FLOAT, lower=0.5, upper=0.9999) betas2 = RangeParameter(name="betas2", parameter_type=ParameterType.FLOAT, lower=0.5, upper=0.9999) emb_scaler = RangeParameter(name="emb_scaler", parameter_type=ParameterType.FLOAT, lower=0.0, upper=1.0) pos_scaler = RangeParameter(name="pos_scaler", parameter_type=ParameterType.FLOAT, lower=0.0, upper=1.0) order_constraint = OrderConstraint(lower_parameter=betas1, upper_parameter=betas2) sum_constraint = SumConstraint(parameters=[emb_scaler, pos_scaler], is_upper_bound=True, bound=1.0) parameter_constraints = [order_constraint, sum_constraint] # %% search space search_space = SearchSpace( parameters=[ RangeParameter(name="batch_size", parameter_type=ParameterType.INT, lower=32, upper=256), RangeParameter(name="fudge", parameter_type=ParameterType.FLOAT, lower=0.0,
def setUp(self): self.x = RangeParameter("x", ParameterType.INT, lower=0, upper=1) self.y = RangeParameter("y", ParameterType.INT, lower=0, upper=1) self.constraint = OrderConstraint(lower_parameter=self.x, upper_parameter=self.y) self.constraint_repr = "OrderConstraint(x <= y)"
def testBadConstruction(self): # Duplicate parameter with self.assertRaises(ValueError): p1 = self.parameters + [self.parameters[0]] SearchSpace(parameters=p1, parameter_constraints=[]) # Constraint on non-existent parameter with self.assertRaises(ValueError): SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=self.a, upper_parameter=self.g) ], ) # Vanilla Constraint on non-existent parameter with self.assertRaises(ValueError): SearchSpace( parameters=self.parameters, parameter_constraints=[ ParameterConstraint(constraint_dict={"g": 1}, bound=0) ], ) # Constraint on non-numeric parameter with self.assertRaises(ValueError): SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=self.a, upper_parameter=self.d) ], ) # Constraint on choice parameter with self.assertRaises(ValueError): SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=self.a, upper_parameter=self.e) ], ) # Constraint on logscale parameter with self.assertRaises(ValueError): SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=self.a, upper_parameter=self.f) ], ) # Constraint on mismatched parameter with self.assertRaises(ValueError): wrong_a = self.a.clone() wrong_a.update_range(upper=10) SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=wrong_a, upper_parameter=self.b) ], )
def setUp(self): self.a = RangeParameter(name="a", parameter_type=ParameterType.FLOAT, lower=0.5, upper=5.5) self.b = RangeParameter(name="b", parameter_type=ParameterType.INT, lower=2, upper=10) self.c = ChoiceParameter(name="c", parameter_type=ParameterType.STRING, values=["foo", "bar", "baz"]) self.d = FixedParameter(name="d", parameter_type=ParameterType.BOOL, value=True) self.e = ChoiceParameter(name="e", parameter_type=ParameterType.FLOAT, values=[0.0, 0.1, 0.2, 0.5]) self.f = RangeParameter( name="f", parameter_type=ParameterType.INT, lower=2, upper=10, log_scale=True, ) self.g = RangeParameter(name="g", parameter_type=ParameterType.FLOAT, lower=0.0, upper=1.0) self.parameters = [self.a, self.b, self.c, self.d, self.e, self.f] self.ss1 = SearchSpace(parameters=self.parameters) self.ss2 = SearchSpace( parameters=self.parameters, parameter_constraints=[ OrderConstraint(lower_parameter=self.a, upper_parameter=self.b) ], ) self.ss1_repr = ( "SearchSpace(" "parameters=[" "RangeParameter(name='a', parameter_type=FLOAT, range=[0.5, 5.5]), " "RangeParameter(name='b', parameter_type=INT, range=[2, 10]), " "ChoiceParameter(name='c', parameter_type=STRING, " "values=['foo', 'bar', 'baz']), " "FixedParameter(name='d', parameter_type=BOOL, value=True), " "ChoiceParameter(name='e', parameter_type=FLOAT, " "values=[0.0, 0.1, 0.2, 0.5]), " "RangeParameter(name='f', parameter_type=INT, range=[2, 10], " "log_scale=True)], " "parameter_constraints=[])") self.ss2_repr = ( "SearchSpace(" "parameters=[" "RangeParameter(name='a', parameter_type=FLOAT, range=[0.5, 5.5]), " "RangeParameter(name='b', parameter_type=INT, range=[2, 10]), " "ChoiceParameter(name='c', parameter_type=STRING, " "values=['foo', 'bar', 'baz']), " "FixedParameter(name='d', parameter_type=BOOL, value=True), " "ChoiceParameter(name='e', parameter_type=FLOAT, " "values=[0.0, 0.1, 0.2, 0.5]), " "RangeParameter(name='f', parameter_type=INT, range=[2, 10], " "log_scale=True)], " "parameter_constraints=[OrderConstraint(a <= b)])")
def testInvalidSetup(self): z = ChoiceParameter("z", ParameterType.STRING, ["a", "b", "c"]) with self.assertRaises(ValueError): self.constraint = OrderConstraint(lower_parameter=self.x, upper_parameter=z)