class_docstr: Implementation of Query-Efficient Black-box Adversarial Examples. The attack approximates the gradient by
  maximizing the loss function over samples drawn from random Gaussian noise around the input.
  
  | Paper link: https://arxiv.org/abs/1712.07113
class_docstr_tok: ["Implementation","of","Query-Efficient","Black-box","Adversarial","Examples",".","The","attack","approximates","the","gradient","by","maximizing","the","loss","function","over","samples","drawn","from","random","Gaussian","noise","around","the","input",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1712.07113"]
docstr: Compute the gradient of the loss function w.r.t. `x`.
  
  :param x: Sample input with shape as expected by the model.
  :param y: Correct labels, one-vs-rest encoding.
  :return: Array of gradients of the same shape as `x`.
docstr_tok: ["Compute","the","gradient","of","the","loss","function","w.r.t",".","`","x","`",".",":","param","x",":","Sample","input","with","shape","as","expected","by","the","model",".",":","param","y",":","Correct","labels",",","one-vs-rest","encoding",".",":","return",":","Array","of","gradients","of","the","same","shape","as","`","x","`","."]
code: def loss_gradient(
      self, x: np.ndarray, y: np.ndarray, **kwargs
  ) -> np.ndarray:
      """
      Compute the gradient of the loss function w.r.t. `x`.
  
      :param x: Sample input with shape as expected by the model.
      :param y: Correct labels, one-vs-rest encoding.
      :return: Array of gradients of the same shape as `x`.
      """
      epsilon_map = self.sigma * np.random.normal(
          size=([self.num_basis] + list(self.input_shape))
      )
      grads = []
      for i in range(len(x)):
          minus, plus = self._generate_samples(
              x[i : i + 1], epsilon_map
          )
  
          # Vectorized; small tests weren't faster
          # ent_vec = np.vectorize(lambda p: entropy(y[i], p), signature='(n)->()')
          # new_y_minus = ent_vec(self.predict(minus))
          # new_y_plus = ent_vec(self.predict(plus))
          # Vanilla
          new_y_minus = np.array(
              [entropy(y[i], p) for p in self.predict(minus)]
          )
          new_y_plus = np.array(
              [entropy(y[i], p) for p in self.predict(plus)]
          )
          query_efficient_grad = 2 * np.mean(
              np.multiply(
                  epsilon_map.reshape(self.num_basis, -1),
                  (new_y_plus - new_y_minus).reshape(self.num_basis, -1)
                  / (2 * self.sigma),
              ).reshape([-1] + list(self.input_shape)),
              axis=0,
          )
          grads.append(query_efficient_grad)
      grads_array = self._apply_preprocessing_gradient(
          x, np.array(grads)
      )
      return grads_array
  
imports: import logging
  from typing import List, Optional, Tuple, Union, TYPE_CHECKING
  import numpy
  from scipy.stats import entropy
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification.classifier import ClassifierMixin, ClassifierLossGradients
  from art.utils import clip_and_round
label_desc: Use image node_id 7 for calling the QueryEfficientGradientEstimationClassifier obj's underlying member method code with example usage: obj.loss_gradient(x, y) and returns: grads_array