class_docstr: Implementation of Sleeper Agent Attack
  
  | Paper link: https://arxiv.org/pdf/2106.08970.pdf
class_docstr_tok: ["Implementation","of","Sleeper","Agent","Attack","|","Paper","link",":","https",":","\/\/arxiv.org\/pdf\/2106.08970.pdf"]
docstr: Optimizes a portion of poisoned samples from x_train to make a model classify x_target
  as y_target by matching the gradients.
  
  :param x_trigger: A list of samples to use as triggers.
  :param y_trigger: A list of target classes to classify the triggers into.
  :param x_train: A list of training data to poison a portion of.
  :param y_train: A list of labels for x_train.
  :return: x_train, y_train and indices of poisoned samples.
           Here, x_train are the samples selected from target class
           in training data.
docstr_tok: ["Optimizes","a","portion","of","poisoned","samples","from","x_train","to","make","a","model","classify","x_target","as","y_target","by","matching","the","gradients",".",":","param","x_trigger",":","A","list","of","samples","to","use","as","triggers",".",":","param","y_trigger",":","A","list","of","target","classes","to","classify","the","triggers","into",".",":","param","x_train",":","A","list","of","training","data","to","poison","a","portion","of",".",":","param","y_train",":","A","list","of","labels","for","x_train",".",":","return",":","x_train",",","y_train","and","indices","of","poisoned","samples",".","Here",",","x_train","are","the","samples","selected","from","target","class","in","training","data","."]
code: def poison(  # type: ignore
      self,
      x_trigger: np.ndarray,
      y_trigger: np.ndarray,
      x_train: np.ndarray,
      y_train: np.ndarray,
      x_test: np.ndarray,
      y_test: np.ndarray,
  ) -> Tuple[np.ndarray, np.ndarray]:
      """
      Optimizes a portion of poisoned samples from x_train to make a model classify x_target
      as y_target by matching the gradients.
  
      :param x_trigger: A list of samples to use as triggers.
      :param y_trigger: A list of target classes to classify the triggers into.
      :param x_train: A list of training data to poison a portion of.
      :param y_train: A list of labels for x_train.
      :return: x_train, y_train and indices of poisoned samples.
               Here, x_train are the samples selected from target class
               in training data.
      """
      # Apply Normalisation
      x_train = np.copy(x_train)
      if isinstance(
          self.substitute_classifier.preprocessing,
          (
              StandardisationMeanStdPyTorch,
              StandardisationMeanStdTensorFlow,
          ),
      ):
          x_trigger = (
              x_trigger - self.substitute_classifier.preprocessing.mean
          ) / self.substitute_classifier.preprocessing.std
          x_train = (
              x_train - self.substitute_classifier.preprocessing.mean
          ) / self.substitute_classifier.preprocessing.std
  
      (
          x_train_target_samples,
          y_train_target_samples,
      ) = self._select_target_train_samples(x_train, y_train)
      if isinstance(self.substitute_classifier, PyTorchClassifier):
          poisoner = self._poison__pytorch
          finish_poisoning = self._finish_poison_pytorch
          initializer = self._initialize_poison_pytorch
      elif isinstance(
          self.substitute_classifier, TensorFlowV2Classifier
      ):
          poisoner = self._poison__tensorflow
          finish_poisoning = self._finish_poison_tensorflow
          initializer = self._initialize_poison_tensorflow
      else:
          raise NotImplementedError(
              "SleeperAgentAttack is currently implemented only for PyTorch and TensorFlowV2."
          )
  
      # Choose samples to poison.
      x_trigger = self._apply_trigger_patch(x_trigger)
      if len(np.shape(y_trigger)) == 2:  # dense labels
          classes_target = set(np.argmax(y_trigger, axis=-1))
      else:  # sparse labels
          classes_target = set(y_trigger)
      num_poison_samples = int(
          self.percent_poison * len(x_train_target_samples)
      )
  
      # Try poisoning num_trials times and choose the best one.
      best_B = np.finfo(np.float32).max  # pylint: disable=C0103
      best_x_poisoned: np.ndarray
      best_indices_poison: np.ndarray
  
      if len(np.shape(y_train)) == 2:
          y_train_classes = np.argmax(y_train_target_samples, axis=-1)
      else:
          y_train_classes = y_train_target_samples
      for _ in trange(self.max_trials):
          if self.selection_strategy == "random":
              self.indices_poison = np.random.permutation(
                  np.where(
                      [y in classes_target for y in y_train_classes]
                  )[0]
              )[:num_poison_samples]
          else:
              self.indices_poison = self._select_poison_indices(
                  self.substitute_classifier,
                  x_train_target_samples,
                  y_train_target_samples,
                  num_poison_samples,
              )
          x_poison = x_train_target_samples[self.indices_poison]
          y_poison = y_train_target_samples[self.indices_poison]
          initializer(x_trigger, y_trigger, x_poison, y_poison)
          if self.model_retrain:
              retrain_epochs = self.max_epochs // self.retraining_factor
              self.max_epochs = retrain_epochs
              for i in range(self.retraining_factor):
                  if i == self.retraining_factor - 1:
                      x_poisoned, B_ = poisoner(
                          x_poison, y_poison
                      )  # pylint: disable=C0103
                  else:
                      x_poisoned, B_ = poisoner(
                          x_poison, y_poison
                      )  # pylint: disable=C0103
                      self._model_retraining(
                          x_poisoned, x_train, y_train, x_test, y_test
                      )
                  self.initial_epoch = self.max_epochs
                  self.max_epochs = self.max_epochs + retrain_epochs
  
          else:
              x_poisoned, B_ = poisoner(
                  x_poison, y_poison
              )  # pylint: disable=C0103
          finish_poisoning()
          B_ = np.mean(
              B_
          )  # Averaging B losses from multiple batches.  # pylint: disable=C0103
          if B_ < best_B:
              best_B = B_  # pylint: disable=C0103
              best_x_poisoned = x_poisoned
              best_indices_poison = self.indices_poison
      if best_B == np.finfo(np.float32).max:
          logger.warning(
              "Attack unsuccessful: all loss values were non-finite. Defaulting to final trial."
          )
          best_B = B_  # pylint: disable=C0103
          best_x_poisoned = x_poisoned
          best_indices_poison = self.indices_poison
      # set indices_poison to be the best indices after all trials
      self.indices_poison = best_indices_poison
  
      # Apply De-Normalization
      if isinstance(
          self.substitute_classifier.preprocessing,
          (
              StandardisationMeanStdPyTorch,
              StandardisationMeanStdTensorFlow,
          ),
      ):
          x_train = (
              x_train * self.substitute_classifier.preprocessing.std
              + self.substitute_classifier.preprocessing.mean
          )
          best_x_poisoned = (
              best_x_poisoned
              * self.substitute_classifier.preprocessing.std
              + self.substitute_classifier.preprocessing.mean
          )
      if self.verbose > 0:
          logger.info("Best B-score: %s", best_B)
      if isinstance(self.substitute_classifier, PyTorchClassifier):
          x_train[
              self.indices_target[best_indices_poison]
          ] = best_x_poisoned
      elif isinstance(
          self.substitute_classifier, TensorFlowV2Classifier
      ):
          x_train[
              self.indices_target[best_indices_poison]
          ] = best_x_poisoned
      else:
          raise NotImplementedError(
              "SleeperAgentAttack is currently implemented only for PyTorch and TensorFlowV2."
          )
      return x_train, y_train
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Tuple, TYPE_CHECKING, List, Union
  import random
  import numpy
  from tqdm.auto import trange
  from art.attacks.poisoning.gradient_matching_attack import GradientMatchingAttack
  from art.estimators.classification.pytorch import PyTorchClassifier
  from art.estimators.classification import TensorFlowV2Classifier
  from art.preprocessing.standardisation_mean_std.pytorch import StandardisationMeanStdPyTorch
  from art.preprocessing.standardisation_mean_std.tensorflow import StandardisationMeanStdTensorFlow
label_desc: Use image node_id 2 for calling the SleeperAgentAttack obj's underlying member method code with example usage: obj.poison(x_trigger, y_trigger, x_train, y_train, x_test, y_test) and returns: x_train,  y_train