class_docstr: Implementation of the attack from Hirano and Takemoto (2019). Computes a fixed perturbation to be applied to all
  future inputs. To this end, it can use any adversarial attack method.
  
  | Paper link: https://arxiv.org/abs/1911.06502
class_docstr_tok: ["Implementation","of","the","attack","from","Hirano","and","Takemoto","(","2019",")",".","Computes","a","fixed","perturbation","to","be","applied","to","all","future","inputs",".","To","this","end",",","it","can","use","any","adversarial","attack","method",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1911.06502"]
docstr: Generate adversarial samples and return them in an array.
  
  :param x: An array with the original inputs.
  :param y: The target labels for the targeted perturbation. The shape of y should match the number of instances
            in x.
  :return: An array holding the adversarial examples.
  :raises: `ValueError`: if the labels `y` are None or if the attack has not been tested for binary
           classification with a single output classifier.
docstr_tok: ["Generate","adversarial","samples","and","return","them","in","an","array",".",":","param","x",":","An","array","with","the","original","inputs",".",":","param","y",":","The","target","labels","for","the","targeted","perturbation",".","The","shape","of","y","should","match","the","number","of","instances","in","x.",":","return",":","An","array","holding","the","adversarial","examples",".",":","raises",":","`","ValueError","`",":","if","the","labels","`","y","`","are","None","or","if","the","attack","has","not","been","tested","for","binary","classification","with","a","single","output","classifier","."]
code: def generate(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> np.ndarray:
      """
      Generate adversarial samples and return them in an array.
  
      :param x: An array with the original inputs.
      :param y: The target labels for the targeted perturbation. The shape of y should match the number of instances
                in x.
      :return: An array holding the adversarial examples.
      :raises: `ValueError`: if the labels `y` are None or if the attack has not been tested for binary
               classification with a single output classifier.
      """
      if y is None:
          raise ValueError("Labels `y` cannot be None.")
  
      if self.estimator.nb_classes == 2 and y.shape[1] == 1:
          raise ValueError(
              "This attack has not yet been tested for binary classification with a single output classifier."
          )
  
      logger.info(
          "Computing targeted universal perturbation based on %s attack.",
          self.attacker,
      )
  
      # Init universal perturbation
      noise = np.zeros_like(x[[0]])
      fooling_rate = 0.0
      targeted_success_rate = 0.0
      nb_instances = len(x)
  
      # Instantiate the middle attacker and get the predicted labels
      attacker = self._get_attack(self.attacker, self.attacker_params)
      pred_y = self.estimator.predict(x, batch_size=1)
      pred_y_max = np.argmax(pred_y, axis=1)
  
      # Start to generate the adversarial examples
      nb_iter = 0
      while (
          targeted_success_rate < 1.0 - self.delta
          and nb_iter < self.max_iter
      ):
          # Go through all the examples randomly
          rnd_idx = random.sample(range(nb_instances), nb_instances)
  
          # Go through the data set and compute the perturbation increments sequentially
          for _, (e_x, e_y) in enumerate(zip(x[rnd_idx], y[rnd_idx])):
              x_i = e_x[None, ...]
              y_i = e_y[None, ...]
  
              current_label = np.argmax(
                  self.estimator.predict(x_i + noise)[0]
              )
              target_label = np.argmax(y_i)
  
              if current_label != target_label:
                  # Compute adversarial perturbation
                  adv_xi = attacker.generate(x_i + noise, y=y_i)
  
                  new_label = np.argmax(
                      self.estimator.predict(adv_xi)[0]
                  )
  
                  # If the class has changed, update v
                  if new_label == target_label:
                      noise = adv_xi - x_i
  
                      # Project on L_p ball
                      noise = projection(noise, self.eps, self.norm)
          nb_iter += 1
  
          # Apply attack and clip
          x_adv = x + noise
          if (
              hasattr(self.estimator, "clip_values")
              and self.estimator.clip_values is not None
          ):
              clip_min, clip_max = self.estimator.clip_values
              x_adv = np.clip(x_adv, clip_min, clip_max)
  
          # Compute the error rate
          y_adv = np.argmax(
              self.estimator.predict(x_adv, batch_size=1), axis=1
          )
          fooling_rate = np.sum(pred_y_max != y_adv) / nb_instances
          targeted_success_rate = (
              np.sum(y_adv == np.argmax(y, axis=1)) / nb_instances
          )
  
      self.fooling_rate = fooling_rate
      self.targeted_success_rate = targeted_success_rate
      self.converged = nb_iter < self.max_iter
      self.noise = noise
      logger.info(
          "Fooling rate of universal perturbation attack: %.2f%%",
          100 * fooling_rate,
      )
      logger.info(
          "Targeted success rate of universal perturbation attack: %.2f%%",
          100 * targeted_success_rate,
      )
  
      return x_adv
  
file_path: adversarial-robustness-toolbox/art/attacks/evasion/targeted_universal_perturbation.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  import random
  import types
  from typing import Any, Dict, Optional, Union, TYPE_CHECKING
  import numpy
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification.classifier import ClassifierMixin
  from art.utils import projection
label_desc: Use image node_id 2 for calling the TargetedUniversalPerturbation obj's underlying member method code with example usage: obj.generate(x, y) and returns: x_adv