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: Initialize poison noises to be optimized.
  
  :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_poison: A list of training data to poison a portion of.
  :param y_poison: A list of true labels for x_poison.
docstr_tok: ["Initialize","poison","noises","to","be","optimized",".",":","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_poison",":","A","list","of","training","data","to","poison","a","portion","of",".",":","param","y_poison",":","A","list","of","true","labels","for","x_poison","."]
code: def _initialize_poison_tensorflow(
      self,
      x_trigger: np.ndarray,
      y_trigger: np.ndarray,
      x_poison: np.ndarray,
      y_poison: np.ndarray,
  ):
      """
      Initialize poison noises to be optimized.
  
      :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_poison: A list of training data to poison a portion of.
      :param y_poison: A list of true labels for x_poison.
      """
      # pylint: disable=no-name-in-module
      from tensorflow.keras import backend as K
      import tensorflow as tf
      from tensorflow.keras.layers import Input, Embedding, Add, Lambda
      from art.estimators.classification.tensorflow import (
          TensorFlowV2Classifier,
      )
  
      if isinstance(self.substitute_classifier, TensorFlowV2Classifier):
          classifier = self.substitute_classifier
      else:
          raise Exception(
              "This method requires `TensorFlowV2Classifier` as `substitute_classifier`'s type"
          )
  
      self.model_trainable = classifier.model.trainable
      classifier.model.trainable = (
          False  # This value gets revert back later.
      )
  
      def _weight_grad(
          classifier: TensorFlowV2Classifier,
          x: tf.Tensor,
          target: tf.Tensor,
      ) -> tf.Tensor:
          # Get the target gradient vector.
          import tensorflow as tf
  
          with tf.GradientTape() as t:  # pylint: disable=C0103
              t.watch(classifier.model.weights)
              output = classifier.model(x, training=False)
              loss = classifier.loss_object(target, output)
          d_w = t.gradient(loss, classifier.model.weights)
          d_w = [w for w in d_w if w is not None]
          d_w = tf.concat([tf.reshape(d, [-1]) for d in d_w], 0)
          d_w_norm = d_w / tf.sqrt(tf.reduce_sum(tf.square(d_w)))
          return d_w_norm
  
      self.grad_ws_norm = _weight_grad(
          classifier, tf.constant(x_trigger), tf.constant(y_trigger)
      )
  
      # Define the model to apply and optimize the poison.
      input_poison = Input(batch_shape=classifier.model.input.shape)
      input_indices = Input(shape=())
      y_true_poison = Input(shape=np.shape(y_poison)[1:])
      embedding_layer = Embedding(
          len(x_poison),
          np.prod(x_poison.shape[1:]),
          embeddings_initializer=tf.keras.initializers.RandomNormal(
              stddev=self.epsilon * 0.01
          ),
      )
      embeddings = embedding_layer(input_indices)
      embeddings = tf.tanh(embeddings) * self.epsilon
      embeddings = tf.reshape(embeddings, tf.shape(input_poison))
      input_noised = Add()([input_poison, embeddings])
      input_noised = Lambda(
          lambda x: K.clip(x, self.clip_values[0], self.clip_values[1])
      )(
          input_noised
      )  # Make sure the poisoned samples are in a valid range.
  
      def loss_fn(
          input_noised: tf.Tensor,
          target: tf.Tensor,
          grad_ws_norm: tf.Tensor,
      ):
          d_w2_norm = _weight_grad(classifier, input_noised, target)
          B = 1 - tf.reduce_sum(
              grad_ws_norm * d_w2_norm
          )  # pylint: disable=C0103
          return B
  
      B = tf.keras.layers.Lambda(
          lambda x: loss_fn(x[0], x[1], x[2])
      )(  # pylint: disable=C0103
          [input_noised, y_true_poison, self.grad_ws_norm]
      )
  
      self.backdoor_model = tf.keras.models.Model(
          [input_poison, y_true_poison, input_indices],
          [input_noised, B],
      )
  
      self.backdoor_model.add_loss(B)
  
      class PredefinedLRSchedule(
          tf.keras.optimizers.schedules.LearningRateSchedule
      ):
          """
          Use a preset learning rate based on the current training epoch.
          """
  
          def __init__(
              self, learning_rates: List[float], milestones: List[int]
          ):
              self.schedule = list(zip(milestones, learning_rates))
  
          def __call__(self, step: int) -> float:
              lr_prev = self.schedule[0][1]
              for m, learning_rate in self.schedule:
                  if step < m:
                      return lr_prev
                  lr_prev = learning_rate
              return lr_prev
  
          def get_config(self) -> Dict:
              """
              Returns the parameters.
              """
              return {"schedule": self.schedule}
  
      self.optimizer = tf.keras.optimizers.legacy.Adam(
          gradient_transformers=[
              lambda grads_and_vars: [
                  (tf.sign(g), v) for (g, v) in grads_and_vars
              ]
          ]
      )
      self.lr_schedule = tf.keras.callbacks.LearningRateScheduler(
          PredefinedLRSchedule(*self.learning_rate_schedule)
      )
  
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 5 for calling the GradientMatchingAttack obj's underlying member method code with example usage: obj._initialize_poison_tensorflow(x_trigger, y_trigger, x_poison, y_poison) and returns: d_w_norm, B, lr_prev, dict, lr_prev