def compute_loss(
        self,
        x: np.ndarray | "tf.Tensor",
        y: np.ndarray | "tf.Tensor",
        reduction: str = "none",
        training_mode: bool = False,
        **kwargs,
    ) -> np.ndarray:
        """
        Compute the loss.

        :param x: Sample input with shape as expected by the model.
        :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)` or indices
                  of shape `(nb_samples,)`.
        :param reduction: Specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'.
                   'none': no reduction will be applied
                   'mean': the sum of the output will be divided by the number of elements in the output,
                   'sum': the output will be summed.
        :param training_mode: `True` for model set to training mode and `False` for model set to evaluation mode.
        :return: Array of losses of the same shape as `x`.
        """
        import tensorflow as tf

        if self._loss_object is None:  # pragma: no cover
            raise TypeError("The loss function `loss_object` is required for computing losses, but it is not defined.")
        prev_reduction = self._loss_object.reduction
        if reduction == "none":
            self._loss_object.reduction = tf.keras.losses.Reduction.NONE
        elif reduction == "mean":
            self._loss_object.reduction = tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE
        elif reduction == "sum":
            self._loss_object.reduction = tf.keras.losses.Reduction.SUM

        y = check_and_transform_label_format(y, self.nb_classes)  # type: ignore

        # Apply preprocessing
        x_preprocessed, y_preprocessed = self._apply_preprocessing(x, y, fit=False)

        if tf.executing_eagerly():
            x_preprocessed_tf = tf.convert_to_tensor(x_preprocessed)
            predictions = self.model(x_preprocessed_tf, training=training_mode)
            if self._reduce_labels:
                loss = self._loss_object(np.argmax(y_preprocessed, axis=1), predictions)
            else:
                loss = self._loss_object(y_preprocessed, predictions)
        else:
            raise NotImplementedError("Expecting eager execution.")

        self._loss_object.reduction = prev_reduction
        return loss.numpy()

        Compute the loss.

        :param x: Sample input with shape as expected by the model.
        :param y: Target values (class labels) one-hot-encoded of shape `(nb_samples, nb_classes)` or indices
                  of shape `(nb_samples,)`.
        :param reduction: Specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'.
                   'none': no reduction will be applied
                   'mean': the sum of the output will be divided by the number of elements in the output,
                   'sum': the output will be summed.
        :param training_mode: `True` for model set to training mode and `False` for model set to evaluation mode.
        :return: Array of losses of the same shape as `x`.
        
art/estimators/classification/tensorflow.py