def test_alamo_object(self, alamo_trainer): alamo_object = alamo_trainer.alamo_object assert isinstance(alamo_object, AlamoSurrogate) assert alamo_object._surrogate_expressions == { 'z1': ' z1 == 3.9999999999925432980774 * x1**2 - ' '4.0000000000020792256805 * x2**2 - ' '2.0999999999859380039879 * x1**4 + ' '4.0000000000043085535140 * x2**4 + ' '0.33333333332782683067208 * x1**6 + ' '0.99999999999973088193883 * x1*x2'} assert alamo_object._input_labels == ["x1", "x2"] assert alamo_object._output_labels == ["z1"] assert alamo_object._input_bounds == { "x1": (-1.5, 1.5), "x2": (-1.5, 1.5)} # Check populating a block to finish workflow blk = SurrogateBlock(concrete=True) blk.build_model(alamo_object) assert isinstance(blk.inputs, Var) assert blk.inputs["x1"].bounds == (-1.5, 1.5) assert blk.inputs["x2"].bounds == (-1.5, 1.5) assert isinstance(blk.outputs, Var) assert blk.outputs["z1"].bounds == (None, None) assert isinstance(blk.alamo_constraint, Constraint) assert len(blk.alamo_constraint) == 1
def test_populate_block_multi(self, alm_surr2): blk = SurrogateBlock(concrete=True) blk.build_model(alm_surr2) assert isinstance(blk.inputs, Var) assert blk.inputs["x1"].bounds == (None, None) assert blk.inputs["x2"].bounds == (None, None) assert isinstance(blk.outputs, Var) assert blk.outputs["z1"].bounds == (None, None) assert blk.outputs["z2"].bounds == (None, None) assert isinstance(blk.alamo_constraint, Constraint) assert len(blk.alamo_constraint) == 2 assert str(blk.alamo_constraint["z1"].body) == ( "outputs[z1] - (" "3.9999999999925446*inputs[x1]**2 - " "4.000000000002077*inputs[x2]**2 - " "2.099999999985938*inputs[x1]**4 + " "4.000000000004311*inputs[x2]**4 + " "0.33333333332782633*inputs[x1]**6 + " "0.9999999999997299*inputs[x1]*inputs[x2])") assert str(blk.alamo_constraint["z2"].body) == ( "outputs[z2] - (" "0.07226779984920294*inputs[x1] + " "0.06845168475391271*inputs[x2] + " "1.0677896915911471*inputs[x1]**2 - " "0.7057646480622435*inputs[x2]**2 - " "0.04028628356655499*inputs[x1]**3 + " "0.006778566802168481*inputs[x2]**5 - " "0.14017881460354553*inputs[x1]**6 + " "0.7720704944157665*inputs[x2]**6 + " "0.4214330995151807*inputs[x1]*inputs[x2] - " "0.041818729807213094)")
def test_keras_surrogate_auto_creating_variables_glpk(): ### # Test 1->2 relu ### keras_surrogate = create_keras_model(name='T_data_1_10_10_2_relu', return_keras_model_only=False) x_test = pd.DataFrame({'Temperature_K': [370]}) y_test = keras_surrogate.evaluate_surrogate(x_test) # Test relu bigm m = ConcreteModel() m.obj = Objective(expr=1) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, formulation=KerasSurrogate.Formulation.RELU_BIGM) m.surrogate.inputs['Temperature_K'].fix(370) solver = SolverFactory('glpk') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol) ### # Test 2->2 relu ### keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_relu', return_keras_model_only=False) x_test = pd.DataFrame({ 'Temperature_K': [370], 'Pressure_Pa': [1.1 * 101325] }) y_test = keras_surrogate.evaluate_surrogate(x_test) # Test relu bigm m = ConcreteModel() m.obj = Objective(expr=1) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, formulation=KerasSurrogate.Formulation.RELU_BIGM) m.surrogate.inputs['Temperature_K'].fix(370) m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325) solver = SolverFactory('glpk') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)
def test_populate_block_funcs(self, alm_surr3): blk = SurrogateBlock(concrete=True) blk.build_model(alm_surr3) assert isinstance(blk.inputs, Var) assert isinstance(blk.outputs, Var) assert isinstance(blk.alamo_constraint, Constraint) assert len(blk.alamo_constraint) == 1 assert str(blk.alamo_constraint["z1"].body) == ( "outputs[z1] - (2*sin(inputs[x1]**2) - 3*cos(inputs[x2]**3) - " "4*log(inputs[x1]**4) + 5*exp(inputs[x2]**5))")
def test_setup_inputs_outputs_no_vars_or_labels(): m = ConcreteModel() m.sb = SurrogateBlock() m.sb._setup_inputs_outputs(4, 5) assert m.sb._input_labels == [0, 1, 2, 3] assert isinstance(m.sb.inputs_set, Set) assert isinstance(m.sb.inputs, Var) for i in m.sb.inputs_set: assert i in m.sb._input_labels assert m.sb.inputs[i].value == 0 assert m.sb._input_vars == [ m.sb.inputs[0], m.sb.inputs[1], m.sb.inputs[2], m.sb.inputs[3] ] assert m.sb._output_labels == [0, 1, 2, 3, 4] assert isinstance(m.sb.outputs_set, Set) assert isinstance(m.sb.outputs, Var) for i in m.sb.outputs_set: assert i in m.sb._output_labels assert m.sb.outputs[i].value == 0 assert m.sb._output_vars == [ m.sb.outputs[0], m.sb.outputs[1], m.sb.outputs[2], m.sb.outputs[3], m.sb.outputs[4] ]
def test_setup_inputs_outputs_w_labels_no_vars(): m = ConcreteModel() m.sb = SurrogateBlock() m.sb._setup_inputs_outputs(4, 5, input_labels=["x1", "x2", "x3", "x4"], output_labels=["z1", "z2", "z3", "z4", "z5"]) assert m.sb._input_labels == ["x1", "x2", "x3", "x4"] assert isinstance(m.sb.inputs_set, Set) assert isinstance(m.sb.inputs, Var) for i in m.sb.inputs_set: assert i in m.sb._input_labels assert m.sb.inputs[i].value == 0 assert m.sb._input_vars == [ m.sb.inputs["x1"], m.sb.inputs["x2"], m.sb.inputs["x3"], m.sb.inputs["x4"] ] assert m.sb._output_labels == ["z1", "z2", "z3", "z4", "z5"] assert isinstance(m.sb.outputs_set, Set) assert isinstance(m.sb.outputs, Var) for i in m.sb.outputs_set: assert i in m.sb._output_labels assert m.sb.outputs[i].value == 0 assert m.sb._output_vars == [ m.sb.outputs["z1"], m.sb.outputs["z2"], m.sb.outputs["z3"], m.sb.outputs["z4"], m.sb.outputs["z5"] ]
def test_setup_inputs_outputs_zero_outputs(): m = ConcreteModel() m.sb = SurrogateBlock() with pytest.raises( ValueError, match='Attempting to create a Surrogate block with no inputs ' 'and/or no outputs. A SurrogateBlock must have at least ' 'one input and output'): m.sb._setup_inputs_outputs(1, 0)
def test_setup_inputs_outputs_output_label_mismatch(): m = ConcreteModel() m.sb = SurrogateBlock() with pytest.raises( ValueError, match='Specifying output_labels to a SurrogateBlock, but the ' 'length does not match n_outputs'): m.sb._setup_inputs_outputs(4, 5, output_labels=["x1"])
def test_invalid_formulation(): keras_surrogate = create_keras_model(name='T_data_1_10_10_2_sigmoid', return_keras_model_only=False) m = ConcreteModel() m.obj = Objective(expr=1) m.surrogate = SurrogateBlock() with pytest.raises(ValueError) as excinfo: m.surrogate.build_model(surrogate_object=keras_surrogate, formulation='foo') assert str(excinfo.value) == 'An unrecognized formulation "foo" was passed ' \ 'to KerasSurrogate.populate_block. Please pass a valid formulation.'
def test_setup_inputs_outputs_input_vars_empty_list(): m = ConcreteModel() m.output_set = ["z1", "z2", "z3", "z4", "z5"] m.outputs = Var(m.output_set) m.sb = SurrogateBlock() with pytest.raises(ValueError, match='Specifying input_vars to a SurrogateBlock, but ' 'the length of the input_vars \(after extracting all' ' the VarData objects\) does not match n_inputs'): m.sb._setup_inputs_outputs(4, 5, input_vars=[], output_vars=m.outputs)
def test_setup_inputs_outputs_output_vars_empty_list(): m = ConcreteModel() m.input_set = Set(initialize=["x1", "x2", "x3", "x4"]) m.inputs = Var(m.input_set) m.sb = SurrogateBlock() with pytest.raises(ValueError, match='Specifying output_vars to a SurrogateBlock, but ' 'the length of the output_vars \(after extracting all' ' the VarData objects\) does not match n_outputs'): m.sb._setup_inputs_outputs(4, 5, input_vars=m.inputs, output_vars=[])
def test_build_model_unused_kwarg(): m = ConcreteModel() m.dummy = DummySurrogate() m.sb = SurrogateBlock() with pytest.raises(ValueError, match="Error in keyword arguments passed to " "build_model. The following arguments were not used: " "\['foo'\]"): m.sb.build_model(m.dummy, use_surrogate_bounds=False, foo=True)
def surr_block(): m = ConcreteModel() m.input_set = Set(initialize=["x1", "x2", "x3", "x4"]) m.output_set = ["z1", "z2", "z3", "z4", "z5"] m.inputs = Var(m.input_set) m.outputs = Var(m.output_set) m.sb = SurrogateBlock() m.sb._setup_inputs_outputs(4, 5, input_vars=m.inputs, output_vars=m.outputs) return m
def test_noscalers(): keras_folder_name = os.path.join(this_file_dir(), 'data', 'keras_models') keras_model = load_keras_json_hd5(keras_folder_name, 'PT_data_2_10_10_2_sigmoid') input_labels = ['Temperature_K', 'Pressure_Pa'] output_labels = ['EnthMol', 'VapFrac'] input_bounds = {'Temperature_K': (-3.0, 3.0), 'Pressure_Pa': (-3.0, 3.0)} keras_surrogate = KerasSurrogate(keras_model=keras_model, input_labels=input_labels, output_labels=output_labels, input_bounds=input_bounds) # check solve with pyomo x_test = pd.DataFrame({'Temperature_K': [0.5], 'Pressure_Pa': [0.5]}) y_test = keras_surrogate.evaluate_surrogate(x_test) m = ConcreteModel() m.obj = Objective(expr=1) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, formulation=KerasSurrogate.Formulation.FULL_SPACE) m.surrogate.inputs['Temperature_K'].fix(0.5) m.surrogate.inputs['Pressure_Pa'].fix(0.5) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, check_dtype=False, rtol=rtol, atol=atol)
def test_build_model_w_bounds(): m = ConcreteModel() m.dummy = DummySurrogate() m.sb = SurrogateBlock() m.sb.build_model(m.dummy, use_surrogate_bounds=True) # Check that the _populate_called attribute was added to the SurrogateBlock assert m.sb._populate_called # Check variables and bounds assert m.sb._input_labels == ["x1", "x2", "x3", "x4"] assert isinstance(m.sb.inputs_set, Set) assert isinstance(m.sb.inputs, Var) for i in m.sb.inputs_set: assert i in m.sb._input_labels assert m.sb.inputs[i].value == 0 assert m.sb.inputs[i]._lb == m.dummy.input_bounds()[i][0] assert m.sb.inputs[i]._ub == m.dummy.input_bounds()[i][1] assert m.sb._input_vars == [ m.sb.inputs["x1"], m.sb.inputs["x2"], m.sb.inputs["x3"], m.sb.inputs["x4"] ] assert m.sb._output_labels == ["z1", "z2", "z3", "z4", "z5"] assert isinstance(m.sb.outputs_set, Set) assert isinstance(m.sb.outputs, Var) for i in m.sb.outputs_set: assert i in m.sb._output_labels assert m.sb.outputs[i].value == 0 assert m.sb._output_vars == [ m.sb.outputs["z1"], m.sb.outputs["z2"], m.sb.outputs["z3"], m.sb.outputs["z4"], m.sb.outputs["z5"] ]
def test_populate_block(self, alm_surr1): blk = SurrogateBlock(concrete=True) blk.build_model(alm_surr1) blk.display() assert isinstance(blk.inputs, Var) assert blk.inputs["x1"].bounds == (0, 5) assert blk.inputs["x2"].bounds == (0, 10) assert isinstance(blk.outputs, Var) assert blk.outputs["z1"].bounds == (None, None) assert isinstance(blk.alamo_constraint, Constraint) assert len(blk.alamo_constraint) == 1 assert str(blk.alamo_constraint["z1"].body) == ( "outputs[z1] - (" "3.9999999999925446*inputs[x1]**2 - " "4.000000000002077*inputs[x2]**2 - " "2.099999999985938*inputs[x1]**4 + " "4.000000000004311*inputs[x2]**4 + " "0.33333333332782633*inputs[x1]**6 + " "0.9999999999997299*inputs[x1]*inputs[x2])")
def test_save_load(): keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_sigmoid', return_keras_model_only=False) new_keras_surrogate = None dname = None with TempfileManager.new_context() as tf: dname = tf.mkdtemp() keras_surrogate.save_to_folder(dname) assert os.path.isdir(dname) assert os.path.isfile(os.path.join(dname, 'idaes_info.json')) new_keras_surrogate = KerasSurrogate.load_from_folder(dname) # Check for clean up assert not os.path.isdir(dname) # check surrogate data members assert new_keras_surrogate._input_labels == [ 'Temperature_K', 'Pressure_Pa' ] assert new_keras_surrogate._output_labels == ['EnthMol', 'VapFrac'] assert sorted(new_keras_surrogate._input_bounds.keys()) == [ 'Pressure_Pa', 'Temperature_K' ] assert new_keras_surrogate._input_bounds['Temperature_K'][ 0] == pytest.approx(360.0) assert new_keras_surrogate._input_bounds['Temperature_K'][ 1] == pytest.approx(380.0) assert new_keras_surrogate._input_bounds['Pressure_Pa'][ 0] == pytest.approx(101325.0) assert new_keras_surrogate._input_bounds['Pressure_Pa'][ 1] == pytest.approx(1.2 * 101325.0) # check input scaler expected_columns = ['Temperature_K', 'Pressure_Pa'] offset_series = pd.Series({ 'Temperature_K': 369.983611, 'Pressure_Pa': 111421.319811 }) factor_series = pd.Series({ 'Temperature_K': 5.836047, 'Pressure_Pa': 5917.954504 }) scaler = new_keras_surrogate._input_scaler assert scaler._expected_columns == expected_columns pd.testing.assert_series_equal(scaler._offset, offset_series, rtol=rtol, atol=atol) pd.testing.assert_series_equal(scaler._factor, factor_series, rtol=rtol, atol=atol) # check output scaler expected_columns = ['EnthMol', 'VapFrac'] offset_series = pd.Series({'EnthMol': 54599.629980, 'VapFrac': 0.403307}) factor_series = pd.Series({'EnthMol': 14654.226615, 'VapFrac': 0.430181}) scaler = new_keras_surrogate._output_scaler assert scaler._expected_columns == expected_columns pd.testing.assert_series_equal(scaler._offset, offset_series, rtol=rtol, atol=atol) pd.testing.assert_series_equal(scaler._factor, factor_series, rtol=rtol, atol=atol) # check evaluation x_test = pd.DataFrame({ 'Temperature_K': [360, 370, 380], 'Pressure_Pa': [1.05 * 101325, 1.10 * 101325, 1.15 * 101325] }) y_test = keras_surrogate.evaluate_surrogate(x_test) expected_y = pd.DataFrame({ 'EnthMol': [40194.5586954288, 48660.288218426984, 75178.30324367314], 'VapFrac': [0.002291496299564877, 0.21942246438431742, 0.9996716243380308] }) pd.testing.assert_frame_equal(y_test, expected_y, rtol=rtol, atol=atol) # check solve with pyomo x_test = pd.DataFrame({ 'Temperature_K': [370], 'Pressure_Pa': [1.1 * 101325] }) y_test = keras_surrogate.evaluate_surrogate(x_test) m = ConcreteModel() m.obj = Objective(expr=1) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, formulation=KerasSurrogate.Formulation.FULL_SPACE) m.surrogate.inputs['Temperature_K'].fix(370) m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)
def test_keras_surrogate_with_variables(): keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_sigmoid', return_keras_model_only=False) x_test = pd.DataFrame({ 'Temperature_K': [370], 'Pressure_Pa': [1.1 * 101325] }) y_test = keras_surrogate.evaluate_surrogate(x_test) # Test provide scalar inputs, auto create outputs m = ConcreteModel() m.obj = Objective(expr=1) m.T = Var() m.P = Var() m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, input_vars=[m.T, m.P], formulation=KerasSurrogate.Formulation.FULL_SPACE) m.T.fix(370) m.P.fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol) # Test provide indexed inputs, auto create outputs m = ConcreteModel() m.obj = Objective(expr=1) m.inputs = Var(['T', 'P']) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, input_vars=[m.inputs], formulation=KerasSurrogate.Formulation.FULL_SPACE) m.inputs['T'].fix(370) m.inputs['P'].fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.surrogate.outputs['EnthMol'])], 'VapFrac': [value(m.surrogate.outputs['VapFrac'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol) # Test auto-create inputs, provide scalar outputs m = ConcreteModel() m.obj = Objective(expr=1) m.H = Var() m.V = Var() m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, output_vars=[m.H, m.V], formulation=KerasSurrogate.Formulation.FULL_SPACE) m.surrogate.inputs['Temperature_K'].fix(370) m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.H)], 'VapFrac': [value(m.V)] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol) # Test auto-create inputs, provide indexed outputs m = ConcreteModel() m.obj = Objective(expr=1) m.outputs = Var(['H', 'V']) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, output_vars=[m.outputs], formulation=KerasSurrogate.Formulation.FULL_SPACE) m.surrogate.inputs['Temperature_K'].fix(370) m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.outputs['H'])], 'VapFrac': [value(m.outputs['V'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol) # Test provide scalar inputs, provide indexed outputs m = ConcreteModel() m.obj = Objective(expr=1) m.T = Var() m.P = Var() m.outputs = Var(['H', 'V']) m.surrogate = SurrogateBlock() m.surrogate.build_model(surrogate_object=keras_surrogate, input_vars=[m.T, m.P], output_vars=[m.outputs], formulation=KerasSurrogate.Formulation.FULL_SPACE) m.T.fix(370) m.P.fix(1.1 * 101325) solver = SolverFactory('ipopt') status = solver.solve(m, tee=True) assert_optimal_termination(status) y_test_pyomo = pd.DataFrame({ 'EnthMol': [value(m.outputs['H'])], 'VapFrac': [value(m.outputs['V'])] }) pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)