def estimate_gradient(self, x: np.ndarray, grad: np.ndarray) -> np.ndarray:
        """
        Provide an estimate of the gradients of preprocessor for the backward pass. If the preprocessor is not
        differentiable, this is an estimate of the gradient, most often replacing the computation performed by the
        preprocessor with the identity function (the default).

        :param x: Input data for which the gradient is estimated. First dimension is the batch size.
        :param grad: Gradient value so far.
        :return: The gradient (estimate) of the defence.
        """
        _, std = broadcastable_mean_std(x, self.mean, self.std)
        gradient_back = grad / std

        return gradient_back

        Provide an estimate of the gradients of preprocessor for the backward pass. If the preprocessor is not
        differentiable, this is an estimate of the gradient, most often replacing the computation performed by the
        preprocessor with the identity function (the default).

        :param x: Input data for which the gradient is estimated. First dimension is the batch size.
        :param grad: Gradient value so far.
        :return: The gradient (estimate) of the defence.
        
art/preprocessing/standardisation_mean_std/numpy.py