class_docstr: Implementation of the hard-label GRAPHITE attack from Feng et al. (2022). This is a physical, black-box attack
  that only requires final class prediction and generates robust physical perturbations that can be applied as
  stickers.
  
  | Paper link: https://arxiv.org/abs/2002.07088
  | Original github link: https://github.com/ryan-feng/GRAPHITE
docstr: Function to boost transform-robustness.
  
  :param x: An array with one original input to be attacked.
  :param x_noise: x in the resolution of the noise size.
  :param x_tar_noise: x_tar in the resolution of the noise size.
  :param mask: An array with a mask to be applied to the adversarial perturbations. Shape needs to be
               broadcastable to the shape of x. Any features for which the mask is zero will not be adversarially
               perturbed.
  :param y: The target label.
  :param obj_width: Estimated width of object in inches for perspective transform.
  :param focal: Estimated focal length in ft for perspective transform.
  :param clip_min: Minimum value of an example.
  :param clip_max: Maximum value of an example.
  :param pts: Optional. A set of points that will set the crop size in the perspective transform.
  :return: attacked image
docstr_tok: ["Function","to","boost","transform-robustness",".",":","param","x",":","An","array","with","one","original","input","to","be","attacked",".",":","param","x_noise",":","x","in","the","resolution","of","the","noise","size",".",":","param","x_tar_noise",":","x_tar","in","the","resolution","of","the","noise","size",".",":","param","mask",":","An","array","with","a","mask","to","be","applied","to","the","adversarial","perturbations",".","Shape","needs","to","be","broadcastable","to","the","shape","of","x",".","Any","features","for","which","the","mask","is","zero","will","not","be","adversarially","perturbed",".",":","param","y",":","The","target","label",".",":","param","obj_width",":","Estimated","width","of","object","in","inches","for","perspective","transform",".",":","param","focal",":","Estimated","focal","length","in","ft","for","perspective","transform",".",":","param","clip_min",":","Minimum","value","of","an","example",".",":","param","clip_max",":","Maximum","value","of","an","example",".",":","param","pts",":","Optional",".","A","set","of","points","that","will","set","the","crop","size","in","the","perspective","transform",".",":","return",":","attacked","image"]
code: def _boost(
      self,
      x: np.ndarray,
      x_noise: np.ndarray,
      x_tar_noise: np.ndarray,
      mask: np.ndarray,
      y: int,
      obj_width: float,
      focal: float,
      clip_min: float,
      clip_max: float,
      pts: Optional[np.ndarray] = None,
  ) -> np.ndarray:
      """
      Function to boost transform-robustness.
  
      :param x: An array with one original input to be attacked.
      :param x_noise: x in the resolution of the noise size.
      :param x_tar_noise: x_tar in the resolution of the noise size.
      :param mask: An array with a mask to be applied to the adversarial perturbations. Shape needs to be
                   broadcastable to the shape of x. Any features for which the mask is zero will not be adversarially
                   perturbed.
      :param y: The target label.
      :param obj_width: Estimated width of object in inches for perspective transform.
      :param focal: Estimated focal length in ft for perspective transform.
      :param clip_min: Minimum value of an example.
      :param clip_max: Maximum value of an example.
      :param pts: Optional. A set of points that will set the crop size in the perspective transform.
      :return: attacked image
      """
  
      xforms = get_transform_params(
          self.num_xforms_boost,
          self.rotation_range,
          self.dist_range,
          self.gamma_range,
          self.crop_percent_range,
          self.off_x_range,
          self.off_y_range,
          self.blur_kernels,
          obj_width,
          focal,
      )
  
      # Initialize
      theta = (x_tar_noise - x_noise) * mask
      query_count = 0
  
      xform_imgs = get_transformed_images(
          x,
          mask,
          xforms,
          1.0,
          theta,
          self.net_size,
          clip_min,
          clip_max,
          pts,
      )
  
      err_rate = run_predictions(
          self.estimator, xform_imgs, y, self.batch_size, True
      )
      query_count += self.num_xforms_boost
  
      best_theta, best_eps = theta, err_rate
  
      # End Initialize
  
      theta, eps = best_theta.copy(), best_eps
  
      opt_count = 0
  
      # gradient free optimization steps
      while True:
          gradient = np.zeros(theta.shape)
          num_q_samples = 10
  
          # Take q samples of random Gaussian noise to use as new directions, calculate transform_robustness
          # Used for gradient estimate
          for _ in range(num_q_samples):
              unit_dir = (
                  np.random.randn(*theta.shape).astype(np.float32)
                  * mask
              )
              unit_dir = unit_dir / np.linalg.norm(unit_dir)
              ttt = theta + self.beta * unit_dir
  
              xform_imgs = get_transformed_images(
                  x,
                  mask,
                  xforms,
                  1.0,
                  ttt,
                  self.net_size,
                  clip_min,
                  clip_max,
                  pts,
              )
              eps_ttt = run_predictions(
                  self.estimator, xform_imgs, y, self.batch_size, True
              )
              opt_count += self.num_xforms_boost
  
              gradient += (eps_ttt - eps) / self.beta * unit_dir
  
          gradient = 1.0 / num_q_samples * gradient
  
          # Take gradient step
          new_theta = theta - self.eta * gradient
          xform_imgs = get_transformed_images(
              x,
              mask,
              xforms,
              1.0,
              new_theta,
              self.net_size,
              clip_min,
              clip_max,
              pts,
          )
          new_eps = run_predictions(
              self.estimator, xform_imgs, y, self.batch_size, True
          )
          opt_count += self.num_xforms_boost
  
          if new_eps < best_eps:
              best_theta, best_eps = new_theta.copy(), new_eps
  
          theta, eps = new_theta.copy(), new_eps
  
          if (
              opt_count + query_count + self.num_xforms_boost * 11
          ) > self.num_boost_queries:
              break
  
      adv_example, _, _ = add_noise(x, mask, 1.0, best_theta)
  
      return adv_example
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Tuple, Union, TYPE_CHECKING, List
  import random
  import numpy
  from art.config import ART_NUMPY_DTYPE
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification import ClassifierMixin
  from art.utils import compute_success, to_categorical, check_and_transform_label_format
  from art.attacks.evasion.graphite.utils import convert_to_network, get_transform_params, add_noise, get_transformed_images, run_predictions, score_fn
label_desc: Use image node_id 9 for calling the GRAPHITEBlackbox obj's underlying member method code with example usage: obj._boost(x, x_noise, x_tar_noise, mask, y, obj_width, focal, clip_min, clip_max, pts) and returns: adv_example