diff --git a/test/test_model_modules/test_abstract_model_class.py b/test/test_model_modules/test_abstract_model_class.py new file mode 100644 index 0000000000000000000000000000000000000000..dfef68d550b07f824ed38e5c7809c00e5386d115 --- /dev/null +++ b/test/test_model_modules/test_abstract_model_class.py @@ -0,0 +1,199 @@ +import keras +import pytest + +from mlair import AbstractModelClass + + +class Paddings: + allowed_paddings = {"pad1": 34, "another_pad": True} + + +class AbstractModelSubClass(AbstractModelClass): + + def __init__(self): + super().__init__(input_shape=(12, 1, 2), output_shape=3) + self.test_attr = "testAttr" + + +class TestAbstractModelClass: + + @pytest.fixture + def amc(self): + return AbstractModelClass(input_shape=(14, 1, 2), output_shape=(3,)) + + @pytest.fixture + def amsc(self): + return AbstractModelSubClass() + + def test_init(self, amc): + assert amc.model is None + # assert amc.loss is None + assert amc.model_name == "AbstractModelClass" + assert amc.custom_objects == {} + assert amc._input_shape == (14, 1, 2) + assert amc._output_shape == 3 + + def test_model_property(self, amc): + amc.model = keras.Model() + assert isinstance(amc.model, keras.Model) is True + + # def test_loss_property(self, amc): + # amc.loss = keras.losses.mean_absolute_error + # assert amc.loss == keras.losses.mean_absolute_error + + def test_compile_options_setter_all_empty(self, amc): + amc.compile_options = None + assert amc.compile_options == {'optimizer': None, + 'loss': None, + 'metrics': None, + 'loss_weights': None, + 'sample_weight_mode': None, + 'weighted_metrics': None, + 'target_tensors': None + } + + def test_compile_options_setter_as_dict(self, amc): + amc.compile_options = {"optimizer": keras.optimizers.SGD(), + "loss": keras.losses.mean_absolute_error, + "metrics": ["mse", "mae"]} + assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) + assert amc.compile_options["loss"] == keras.losses.mean_absolute_error + assert amc.compile_options["metrics"] == ["mse", "mae"] + assert amc.compile_options["loss_weights"] is None + assert amc.compile_options["sample_weight_mode"] is None + assert amc.compile_options["target_tensors"] is None + assert amc.compile_options["weighted_metrics"] is None + + def test_compile_options_setter_as_attr(self, amc): + amc.optimizer = keras.optimizers.SGD() + amc.loss = keras.losses.mean_absolute_error + amc.compile_options = None # This line has to be called! + # optimizer check + assert isinstance(amc.optimizer, keras.optimizers.SGD) + assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) + # loss check + assert amc.loss == keras.losses.mean_absolute_error + assert amc.compile_options["loss"] == keras.losses.mean_absolute_error + # check rest (all None as not set) + assert amc.compile_options["metrics"] is None + assert amc.compile_options["loss_weights"] is None + assert amc.compile_options["sample_weight_mode"] is None + assert amc.compile_options["target_tensors"] is None + assert amc.compile_options["weighted_metrics"] is None + + def test_compile_options_setter_as_mix_attr_dict_no_duplicates(self, amc): + amc.optimizer = keras.optimizers.SGD() + amc.compile_options = {"loss": keras.losses.mean_absolute_error, + "loss_weights": [0.2, 0.8]} + # check setting by attribute + assert isinstance(amc.optimizer, keras.optimizers.SGD) + assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) + # check setting by dict + assert amc.compile_options["loss"] == keras.losses.mean_absolute_error + assert amc.compile_options["loss_weights"] == [0.2, 0.8] + # check rest (all None as not set) + assert amc.compile_options["metrics"] is None + assert amc.compile_options["sample_weight_mode"] is None + assert amc.compile_options["target_tensors"] is None + assert amc.compile_options["weighted_metrics"] is None + + def test_compile_options_setter_as_mix_attr_dict_valid_duplicates_optimizer(self, amc): + amc.optimizer = keras.optimizers.SGD() + amc.metrics = ['mse'] + amc.compile_options = {"optimizer": keras.optimizers.SGD(), + "loss": keras.losses.mean_absolute_error} + # check duplicate (attr and dic) + assert isinstance(amc.optimizer, keras.optimizers.SGD) + assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) + # check setting by dict + assert amc.compile_options["loss"] == keras.losses.mean_absolute_error + # check setting by attr + assert amc.metrics == ['mse'] + assert amc.compile_options["metrics"] == ['mse'] + # check rest (all None as not set) + assert amc.compile_options["loss_weights"] is None + assert amc.compile_options["sample_weight_mode"] is None + assert amc.compile_options["target_tensors"] is None + assert amc.compile_options["weighted_metrics"] is None + + def test_compile_options_setter_as_mix_attr_dict_valid_duplicates_none_optimizer(self, amc): + amc.optimizer = keras.optimizers.SGD() + amc.metrics = ['mse'] + amc.compile_options = {"metrics": ['mse'], + "loss": keras.losses.mean_absolute_error} + # check duplicate (attr and dic) + assert amc.metrics == ['mse'] + assert amc.compile_options["metrics"] == ['mse'] + # check setting by dict + assert amc.compile_options["loss"] == keras.losses.mean_absolute_error + # check setting by attr + assert isinstance(amc.optimizer, keras.optimizers.SGD) + assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) + # check rest (all None as not set) + assert amc.compile_options["loss_weights"] is None + assert amc.compile_options["sample_weight_mode"] is None + assert amc.compile_options["target_tensors"] is None + assert amc.compile_options["weighted_metrics"] is None + + def test_compile_options_property_type_error(self, amc): + with pytest.raises(TypeError) as einfo: + amc.compile_options = 'hello world' + assert "`compile_options' must be `dict' or `None', but is <class 'str'>." in str(einfo.value) + + def test_compile_options_setter_as_mix_attr_dict_invalid_duplicates_other_optimizer(self, amc): + amc.optimizer = keras.optimizers.SGD() + with pytest.raises(ValueError) as einfo: + amc.compile_options = {"optimizer": keras.optimizers.Adam()} + assert "Got different values or arguments for same argument: self.optimizer=<class" \ + " 'keras.optimizers.SGD'> and 'optimizer': <class 'keras.optimizers.Adam'>" in str(einfo.value) + + def test_compile_options_setter_as_mix_attr_dict_invalid_duplicates_same_optimizer_other_args(self, amc): + amc.optimizer = keras.optimizers.SGD(lr=0.1) + with pytest.raises(ValueError) as einfo: + amc.compile_options = {"optimizer": keras.optimizers.SGD(lr=0.001)} + assert "Got different values or arguments for same argument: self.optimizer=<class" \ + " 'keras.optimizers.SGD'> and 'optimizer': <class 'keras.optimizers.SGD'>" in str(einfo.value) + + def test_compile_options_setter_as_dict_invalid_keys(self, amc): + with pytest.raises(ValueError) as einfo: + amc.compile_options = {"optimizer": keras.optimizers.SGD(), "InvalidKeyword": [1, 2, 3]} + assert "Got invalid key for compile_options. dict_keys(['optimizer', 'InvalidKeyword'])" in str(einfo.value) + + def test_compare_keras_optimizers_equal(self, amc): + assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(), keras.optimizers.SGD()) is True + + def test_compare_keras_optimizers_no_optimizer(self, amc): + assert amc._AbstractModelClass__compare_keras_optimizers('NoOptimizer', keras.optimizers.SGD()) is False + + def test_compare_keras_optimizers_other_parameters_run_sess(self, amc): + assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(lr=0.1), + keras.optimizers.SGD(lr=0.01)) is False + + def test_compare_keras_optimizers_other_parameters_none_sess(self, amc): + assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(decay=1), + keras.optimizers.SGD(decay=0.01)) is False + + def test_getattr(self, amc): + amc.model = keras.Model() + assert hasattr(amc, "compile") is True + assert hasattr(amc.model, "compile") is True + assert amc.compile == amc.model.compile + + def test_get_settings(self, amc, amsc): + assert amc.get_settings() == {"model_name": "AbstractModelClass", "_input_shape": (14, 1, 2), + "_output_shape": 3} + assert amsc.get_settings() == {"test_attr": "testAttr", "model_name": "AbstractModelSubClass", + "_input_shape": (12, 1, 2), "_output_shape": 3} + + def test_custom_objects(self, amc): + amc.custom_objects = {"Test": 123} + assert amc.custom_objects == {"Test": 123} + + def test_set_custom_objects(self, amc): + amc.set_custom_objects(Test=22, minor_param="minor") + assert amc.custom_objects == {"Test": 22, "minor_param": "minor"} + amc.set_custom_objects(Test=2, minor_param1="minor1") + assert amc.custom_objects == {"Test": 2, "minor_param1": "minor1"} + paddings = Paddings() + amc.set_custom_objects(Test=1, Padding2D=paddings) + assert amc.custom_objects == {"Test": 1, "Padding2D": paddings, "pad1": 34, "another_pad": True} diff --git a/test/test_model_modules/test_flatten_tail.py b/test/test_model_modules/test_flatten_tail.py index 46d63e75f7784a0473685f70d0de8f050a095262..623d51c07f6b27c8d6238d8a5189dea33837115e 100644 --- a/test/test_model_modules/test_flatten_tail.py +++ b/test/test_model_modules/test_flatten_tail.py @@ -91,7 +91,7 @@ class TestFlattenTail: assert final_dropout.rate == 0.35 inner_act = self.step_in(final_dropout) - assert inner_act.get_config() == {'name': 'activation_3', 'trainable': True, 'activation': 'tanh'} + assert inner_act.get_config() == {'name': 'activation_1', 'trainable': True, 'activation': 'tanh'} inner_dense = self.step_in(inner_act) assert inner_dense.units == 64 diff --git a/test/test_model_modules/test_model_class.py b/test/test_model_modules/test_model_class.py index f93f9154350c3b81a9e9218c9809813344126990..cbff4cec6c5b002c3166954880e1008e7f4d7ae3 100644 --- a/test/test_model_modules/test_model_class.py +++ b/test/test_model_modules/test_model_class.py @@ -1,205 +1,9 @@ import keras import pytest -from mlair.model_modules import AbstractModelClass from mlair.model_modules.model_class import MyPaperModel -class Paddings: - allowed_paddings = {"pad1": 34, "another_pad": True} - - -class AbstractModelSubClass(AbstractModelClass): - - def __init__(self): - super().__init__(input_shape=(12, 1, 2), output_shape=3) - self.test_attr = "testAttr" - - -class TestAbstractModelClass: - - @pytest.fixture - def amc(self): - return AbstractModelClass(input_shape=(14, 1, 2), output_shape=(3,)) - - @pytest.fixture - def amsc(self): - return AbstractModelSubClass() - - def test_init(self, amc): - assert amc.model is None - # assert amc.loss is None - assert amc.model_name == "AbstractModelClass" - assert amc.custom_objects == {} - assert amc._input_shape == (14, 1, 2) - assert amc._output_shape == 3 - - def test_model_property(self, amc): - amc.model = keras.Model() - assert isinstance(amc.model, keras.Model) is True - - # def test_loss_property(self, amc): - # amc.loss = keras.losses.mean_absolute_error - # assert amc.loss == keras.losses.mean_absolute_error - - def test_compile_options_setter_all_empty(self, amc): - amc.compile_options = None - assert amc.compile_options == {'optimizer': None, - 'loss': None, - 'metrics': None, - 'loss_weights': None, - 'sample_weight_mode': None, - 'weighted_metrics': None, - 'target_tensors': None - } - - def test_compile_options_setter_as_dict(self, amc): - amc.compile_options = {"optimizer": keras.optimizers.SGD(), - "loss": keras.losses.mean_absolute_error, - "metrics": ["mse", "mae"]} - assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) - assert amc.compile_options["loss"] == keras.losses.mean_absolute_error - assert amc.compile_options["metrics"] == ["mse", "mae"] - assert amc.compile_options["loss_weights"] is None - assert amc.compile_options["sample_weight_mode"] is None - assert amc.compile_options["target_tensors"] is None - assert amc.compile_options["weighted_metrics"] is None - - def test_compile_options_setter_as_attr(self, amc): - amc.optimizer = keras.optimizers.SGD() - amc.loss = keras.losses.mean_absolute_error - amc.compile_options = None # This line has to be called! - # optimizer check - assert isinstance(amc.optimizer, keras.optimizers.SGD) - assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) - # loss check - assert amc.loss == keras.losses.mean_absolute_error - assert amc.compile_options["loss"] == keras.losses.mean_absolute_error - # check rest (all None as not set) - assert amc.compile_options["metrics"] is None - assert amc.compile_options["loss_weights"] is None - assert amc.compile_options["sample_weight_mode"] is None - assert amc.compile_options["target_tensors"] is None - assert amc.compile_options["weighted_metrics"] is None - - def test_compile_options_setter_as_mix_attr_dict_no_duplicates(self, amc): - amc.optimizer = keras.optimizers.SGD() - amc.compile_options = {"loss": keras.losses.mean_absolute_error, - "loss_weights": [0.2, 0.8]} - # check setting by attribute - assert isinstance(amc.optimizer, keras.optimizers.SGD) - assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) - # check setting by dict - assert amc.compile_options["loss"] == keras.losses.mean_absolute_error - assert amc.compile_options["loss_weights"] == [0.2, 0.8] - # check rest (all None as not set) - assert amc.compile_options["metrics"] is None - assert amc.compile_options["sample_weight_mode"] is None - assert amc.compile_options["target_tensors"] is None - assert amc.compile_options["weighted_metrics"] is None - - def test_compile_options_setter_as_mix_attr_dict_valid_duplicates_optimizer(self, amc): - amc.optimizer = keras.optimizers.SGD() - amc.metrics = ['mse'] - amc.compile_options = {"optimizer": keras.optimizers.SGD(), - "loss": keras.losses.mean_absolute_error} - # check duplicate (attr and dic) - assert isinstance(amc.optimizer, keras.optimizers.SGD) - assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) - # check setting by dict - assert amc.compile_options["loss"] == keras.losses.mean_absolute_error - # check setting by attr - assert amc.metrics == ['mse'] - assert amc.compile_options["metrics"] == ['mse'] - # check rest (all None as not set) - assert amc.compile_options["loss_weights"] is None - assert amc.compile_options["sample_weight_mode"] is None - assert amc.compile_options["target_tensors"] is None - assert amc.compile_options["weighted_metrics"] is None - - def test_compile_options_setter_as_mix_attr_dict_valid_duplicates_none_optimizer(self, amc): - amc.optimizer = keras.optimizers.SGD() - amc.metrics = ['mse'] - amc.compile_options = {"metrics": ['mse'], - "loss": keras.losses.mean_absolute_error} - # check duplicate (attr and dic) - assert amc.metrics == ['mse'] - assert amc.compile_options["metrics"] == ['mse'] - # check setting by dict - assert amc.compile_options["loss"] == keras.losses.mean_absolute_error - # check setting by attr - assert isinstance(amc.optimizer, keras.optimizers.SGD) - assert isinstance(amc.compile_options["optimizer"], keras.optimizers.SGD) - # check rest (all None as not set) - assert amc.compile_options["loss_weights"] is None - assert amc.compile_options["sample_weight_mode"] is None - assert amc.compile_options["target_tensors"] is None - assert amc.compile_options["weighted_metrics"] is None - - def test_compile_options_property_type_error(self, amc): - with pytest.raises(TypeError) as einfo: - amc.compile_options = 'hello world' - assert "`compile_options' must be `dict' or `None', but is <class 'str'>." in str(einfo.value) - - def test_compile_options_setter_as_mix_attr_dict_invalid_duplicates_other_optimizer(self, amc): - amc.optimizer = keras.optimizers.SGD() - with pytest.raises(ValueError) as einfo: - amc.compile_options = {"optimizer": keras.optimizers.Adam()} - assert "Got different values or arguments for same argument: self.optimizer=<class" \ - " 'keras.optimizers.SGD'> and 'optimizer': <class 'keras.optimizers.Adam'>" in str(einfo.value) - - def test_compile_options_setter_as_mix_attr_dict_invalid_duplicates_same_optimizer_other_args(self, amc): - amc.optimizer = keras.optimizers.SGD(lr=0.1) - with pytest.raises(ValueError) as einfo: - amc.compile_options = {"optimizer": keras.optimizers.SGD(lr=0.001)} - assert "Got different values or arguments for same argument: self.optimizer=<class" \ - " 'keras.optimizers.SGD'> and 'optimizer': <class 'keras.optimizers.SGD'>" in str(einfo.value) - - def test_compile_options_setter_as_dict_invalid_keys(self, amc): - with pytest.raises(ValueError) as einfo: - amc.compile_options = {"optimizer": keras.optimizers.SGD(), "InvalidKeyword": [1, 2, 3]} - assert "Got invalid key for compile_options. dict_keys(['optimizer', 'InvalidKeyword'])" in str(einfo.value) - - def test_compare_keras_optimizers_equal(self, amc): - assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(), keras.optimizers.SGD()) is True - - def test_compare_keras_optimizers_no_optimizer(self, amc): - assert amc._AbstractModelClass__compare_keras_optimizers('NoOptimizer', keras.optimizers.SGD()) is False - - def test_compare_keras_optimizers_other_parameters_run_sess(self, amc): - assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(lr=0.1), - keras.optimizers.SGD(lr=0.01)) is False - - def test_compare_keras_optimizers_other_parameters_none_sess(self, amc): - assert amc._AbstractModelClass__compare_keras_optimizers(keras.optimizers.SGD(decay=1), - keras.optimizers.SGD(decay=0.01)) is False - - def test_getattr(self, amc): - amc.model = keras.Model() - assert hasattr(amc, "compile") is True - assert hasattr(amc.model, "compile") is True - assert amc.compile == amc.model.compile - - def test_get_settings(self, amc, amsc): - assert amc.get_settings() == {"model_name": "AbstractModelClass", "_input_shape": (14, 1, 2), - "_output_shape": 3} - assert amsc.get_settings() == {"test_attr": "testAttr", "model_name": "AbstractModelSubClass", - "_input_shape": (12, 1, 2), "_output_shape": 3} - - def test_custom_objects(self, amc): - amc.custom_objects = {"Test": 123} - assert amc.custom_objects == {"Test": 123} - - def test_set_custom_objects(self, amc): - amc.set_custom_objects(Test=22, minor_param="minor") - assert amc.custom_objects == {"Test": 22, "minor_param": "minor"} - amc.set_custom_objects(Test=2, minor_param1="minor1") - assert amc.custom_objects == {"Test": 2, "minor_param1": "minor1"} - paddings = Paddings() - amc.set_custom_objects(Test=1, Padding2D=paddings) - assert amc.custom_objects == {"Test": 1, "Padding2D": paddings, "pad1": 34, "another_pad": True} - - class TestMyPaperModel: @pytest.fixture