def class_gradient(  # type: ignore
        self, x: np.ndarray, label: int | list[int] | np.ndarray | None = None, eps: float = 0.0001, **kwargs
    ) -> np.ndarray:
        """
        Compute per-class derivatives w.r.t. `x`.

        :param x: Sample input with shape as expected by the model.
        :param label: Index of a specific per-class derivative. If an integer is provided, the gradient of that class
                      output is computed for all samples. If multiple values as provided, the first dimension should
                      match the batch size of `x`, and each value will be used as target for its corresponding sample in
                      `x`. If `None`, then gradients for all classes will be computed for each sample.
        :param eps: Fraction added to the diagonal elements of the input `x`.
        :return: Array of gradients of input features w.r.t. each class in the form
                 `(batch_size, nb_classes, input_shape)` when computing for all classes, otherwise shape becomes
                 `(batch_size, 1, input_shape)` when `label` parameter is specified.
        """
        # Apply preprocessing
        x_preprocessed, _ = self._apply_preprocessing(x, y=None, fit=False)

        grads = np.zeros((np.shape(x_preprocessed)[0], 2, np.shape(x)[1]))
        for i in range(np.shape(x_preprocessed)[0]):
            # Get gradient for the two classes GPC can maximally have
            for i_c in range(2):
                ind = self.predict(x[i].reshape(1, -1))[0, i_c]
                sur = self.predict(
                    np.repeat(x_preprocessed[i].reshape(1, -1), np.shape(x_preprocessed)[1], 0)
                    + eps * np.eye(np.shape(x_preprocessed)[1])
                )[:, i_c]
                grads[i, i_c] = ((sur - ind) * eps).reshape(1, -1)

        grads = self._apply_preprocessing_gradient(x, grads)

        if label is not None:
            return grads[:, label, :].reshape(np.shape(x_preprocessed)[0], 1, np.shape(x_preprocessed)[1])

        return grads

        Compute per-class derivatives w.r.t. `x`.

        :param x: Sample input with shape as expected by the model.
        :param label: Index of a specific per-class derivative. If an integer is provided, the gradient of that class
                      output is computed for all samples. If multiple values as provided, the first dimension should
                      match the batch size of `x`, and each value will be used as target for its corresponding sample in
                      `x`. If `None`, then gradients for all classes will be computed for each sample.
        :param eps: Fraction added to the diagonal elements of the input `x`.
        :return: Array of gradients of input features w.r.t. each class in the form
                 `(batch_size, nb_classes, input_shape)` when computing for all classes, otherwise shape becomes
                 `(batch_size, 1, input_shape)` when `label` parameter is specified.
        
art/estimators/classification/GPy.py