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: Optimize the poison by matching the gradient within the perturbation budget.
  
  :param x_poison: List of samples to poison.
  :param y_poison: List of the labels for x_poison.
  :return: A pair of poisoned samples, B-score (cosine similarity of the gradients).
docstr_tok: ["Optimize","the","poison","by","matching","the","gradient","within","the","perturbation","budget",".",":","param","x_poison",":","List","of","samples","to","poison",".",":","param","y_poison",":","List","of","the","labels","for","x_poison",".",":","return",":","A","pair","of","poisoned","samples",",","B-score","(","cosine","similarity","of","the","gradients",")","."]
code: def _poison__pytorch(
      self, x_poison: np.ndarray, y_poison: np.ndarray
  ) -> Tuple[Any, Any]:
      """
      Optimize the poison by matching the gradient within the perturbation budget.
  
      :param x_poison: List of samples to poison.
      :param y_poison: List of the labels for x_poison.
      :return: A pair of poisoned samples, B-score (cosine similarity of the gradients).
      """
  
      import torch
  
      device = "cuda" if torch.cuda.is_available() else "cpu"
  
      class PoisonDataset(torch.utils.data.Dataset):
          """
          Iterator for a dataset to poison.
          """
  
          def __init__(self, x: np.ndarray, y: np.ndarray):
              self.len = x.shape[0]
              self.x = torch.as_tensor(x, dtype=torch.float)
              self.y = torch.as_tensor(y)
  
          def __getitem__(self, index):
              return (
                  self.x[index],
                  torch.as_tensor([index]),
                  self.y[index],
              )
  
          def __len__(self):
              return self.len
  
      trainloader = torch.utils.data.DataLoader(
          PoisonDataset(x_poison, y_poison),
          batch_size=self.batch_size,
          shuffle=False,
          num_workers=1,
      )
  
      epoch_iterator = (
          trange(self.initial_epoch, self.max_epochs)
          if self.verbose > 0
          else range(self.initial_epoch, self.max_epochs)
      )
      for _ in epoch_iterator:
          batch_iterator = (
              tqdm(trainloader)
              if isinstance(self.verbose, int) and self.verbose >= 2
              else trainloader
          )
          sum_loss = 0
          count = 0
          for x, indices, y in batch_iterator:
              x = x.to(device)
              y = y.to(device)
              indices = indices.to(device)
              self.backdoor_model.zero_grad()
              loss, poisoned_samples = self.backdoor_model(
                  x, indices, y, self.grad_ws_norm
              )
              loss.backward()
              self.backdoor_model.noise_embedding.embedding_layer.weight.grad.sign_()
              self.optimizer.step()
              sum_loss += loss.clone().cpu().detach().numpy()
              count += 1
          if self.verbose > 0:
              epoch_iterator.set_postfix(loss=sum_loss / count)
          self.lr_schedule.step()
  
      B_sum = 0  # pylint: disable=C0103
      count = 0
      all_poisoned_samples = []
      self.backdoor_model.eval()
      poisonloader = torch.utils.data.DataLoader(
          PoisonDataset(x_poison, y_poison),
          batch_size=self.batch_size,
          shuffle=False,
          num_workers=1,
      )
      for x, indices, y in poisonloader:
          x = x.to(device)
          y = y.to(device)
          indices = indices.to(device)
          B, poisoned_samples = self.backdoor_model(
              x, indices, y, self.grad_ws_norm
          )  # pylint: disable=C0103
          all_poisoned_samples.append(
              poisoned_samples.detach().cpu().numpy()
          )
          B_sum += B.detach().cpu().numpy()  # pylint: disable=C0103
          count += 1
      return np.concatenate(all_poisoned_samples, axis=0), B_sum / count
  
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 8 for calling the GradientMatchingAttack obj's underlying member method code with example usage: obj._poison__pytorch(x_poison, y_poison) and returns: np,  unknown, self,  torch,  self, self