def _check_model_compatibility(self, y: np.ndarray) -> None: """Checks that the model output number and y shape match. This is in place to avoid cryptic TF errors. """ # check if this is a multi-output model if hasattr(self, "n_outputs_expected_"): # n_outputs_expected_ is generated by data transformers # we recognize the attribute but do not force it to be # generated if self.n_outputs_expected_ != len(self.model_.outputs): raise ValueError("Detected a Keras model input of size" f" {y[0].shape[0]}, but {self.model_} has" f" {self.model_.outputs} outputs") # check that if the user gave us a loss function it ended up in # the actual model init_params = inspect.signature(self.__init__).parameters if "loss" in init_params: default_val = init_params["loss"].default if all( isinstance(x, (str, losses_module.Loss, type)) for x in [self.loss, self.model_.loss ]): # filter out loss list/dicts/etc. if default_val is not None: default_val = loss_name(default_val) given = loss_name(self.loss) got = loss_name(self.model_.loss) if given != default_val and got != given: raise ValueError( f"loss={self.loss} but model compiled with {self.model_.loss}." " Data may not match loss function!")
def test_unknown_loss_raises(): with pytest.raises(ValueError, match="Unknown loss function"): loss_name("unknown_loss")
def test_loss_types(loss): with pytest.raises(TypeError, match="`loss` must be a"): loss_name(loss)
def test_custom_loss(obj): assert loss_name(obj) == "custom_loss"
def test_loss_invariance(obj): """Test to make sure loss_name returns same string no matter which object is passed (str, function, class, type)""" assert loss_name(obj) == "categorical_crossentropy"