class_docstr: Implementation of Gradient Matching Attack by Geiping, et. al. 2020.
  "Witches' Brew: Industrial Scale Data Poisoning via Gradient Matching"
  
  | Paper link: https://arxiv.org/abs/2009.02276
class_docstr_tok: ["Implementation","of","Gradient","Matching","Attack","by","Geiping",",","et",".","al",".","2020",".","``","Witches","'","Brew",":","Industrial","Scale","Data","Poisoning","via","Gradient","Matching","''","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/2009.02276"]
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: A list of poisoned samples, and y_train.
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",":","A","list","of","poisoned","samples",",","and","y_train","."]
code: def poison(
      self,
      x_trigger: np.ndarray,
      y_trigger: np.ndarray,
      x_train: np.ndarray,
      y_train: 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: A list of poisoned samples, and y_train.
      """
      from art.estimators.classification.pytorch import (
          PyTorchClassifier,
      )
      from art.estimators.classification.tensorflow import (
          TensorFlowV2Classifier,
      )
  
      if isinstance(self.substitute_classifier, TensorFlowV2Classifier):
          poisoner = self._poison__tensorflow
          finish_poisoning = self._finish_poison_tensorflow
      elif isinstance(self.substitute_classifier, PyTorchClassifier):
          poisoner = self._poison__pytorch
          finish_poisoning = self._finish_poison_pytorch
      else:
          raise NotImplementedError(
              "GradientMatchingAttack is currently implemented only for Tensorflow V2 and Pytorch."
          )
  
      # Choose samples to poison.
      x_train = np.copy(x_train)
      y_train = np.copy(y_train)
      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))
  
      # Try poisoning num_trials times and choose the best one.
      best_B = np.finfo(np.float32).max  # pylint: disable=C0103
      best_x_poisoned = None
      best_indices_poison = None
  
      if len(np.shape(y_train)) == 2:
          y_train_classes = np.argmax(y_train, axis=-1)
      else:
          y_train_classes = y_train
      for _ in trange(self.max_trials):
          indices_poison = np.random.permutation(
              np.where([y in classes_target for y in y_train_classes])[
                  0
              ]
          )[:num_poison_samples]
          x_poison = x_train[indices_poison]
          y_poison = y_train[indices_poison]
          self._initialize_poison(
              x_trigger, y_trigger, x_poison, y_poison
          )
          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 = indices_poison
  
      if self.verbose > 0:
          print("Best B-score:", best_B)
      x_train[best_indices_poison] = best_x_poisoned
      return x_train, y_train
  
file_path: adversarial-robustness-toolbox/art/attacks/poisoning/gradient_matching_attack.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Any, Dict, Tuple, TYPE_CHECKING, List
  import numpy
  from tqdm.auto import trange, tqdm
  from art.attacks.attack import Attack
  from art.estimators import BaseEstimator, NeuralNetworkMixin
  from art.estimators.classification.classifier import ClassifierMixin
label_desc: Use image node_id 7 for calling the GradientMatchingAttack obj's underlying member method code with example usage: obj.poison(x_trigger, y_trigger, x_train, y_train) and returns: x_train,  y_train