class_docstr: This class represent a Feature Adversaries evasion attack in TensorFlow v2.
  
  | Paper link: https://arxiv.org/abs/1511.05122
docstr: Generate adversarial batch.
  
  :param x: Source samples.
  :param y: Guide samples.
  :return: Batch of adversarial examples.
code: def _generate_batch(
      self, x: "tf.Tensor", y: "tf.Tensor"
  ) -> "tf.Tensor":
      """
      Generate adversarial batch.
  
      :param x: Source samples.
      :param y: Guide samples.
      :return: Batch of adversarial examples.
      """
      import tensorflow as tf
  
      def loss_fn(source_orig, source_adv, guide):
          representation_loss = tf.zeros(
              shape=(source_orig.shape[0],), dtype=tf.float32
          )
          for layer_i in self.layer:
              adv_representation = self.estimator.get_activations(
                  source_adv, layer_i, self.batch_size, True
              )
              guide_representation = self.estimator.get_activations(
                  guide, layer_i, self.batch_size, True
              )
  
              axis = tuple(range(1, len(source_adv.shape)))
              soft_constraint = tf.cast(
                  tf.math.reduce_max(
                      tf.abs(source_adv - source_orig), axis=axis
                  ),
                  tf.float32,
              )
  
              axis = tuple(range(1, len(adv_representation.shape)))
              representation_loss += tf.reduce_sum(
                  tf.square(adv_representation - guide_representation),
                  axis=axis,
              )
  
          loss = tf.math.reduce_mean(
              representation_loss + self.lambda_ * soft_constraint
          )
          return loss
  
      adv = tf.identity(x)
      if self.random_start:
          # Starting at a uniformly random point
          adv = adv + tf.random.uniform(
              x.shape, -self.delta, self.delta
          )
          if self.estimator.clip_values is not None:
              adv = tf.clip_by_value(adv, *self.estimator.clip_values)
  
      if self.optimizer is None:
          # run a plain-vanilla PGD
          for _ in trange(
              self.max_iter,
              desc="Feature Adversaries TensorFlow v2",
              disable=not self.verbose,
          ):
              with tf.GradientTape(
                  watch_accessed_variables=False
              ) as tape:
                  tape.watch(adv)
                  loss = loss_fn(x, adv, y)
              gradient = tape.gradient(loss, adv)
  
              # pgd step
              adv = adv - tf.math.sign(gradient) * self.step_size
              perturbation = tf.clip_by_value(
                  adv - x, -self.delta, self.delta
              )
              adv = x + perturbation
              if self.estimator.clip_values is not None:
                  adv = tf.clip_by_value(
                      x + perturbation, *self.estimator.clip_values
                  )
      else:
          # optimize soft constraint problem with chosen optimizer
          opt = self.optimizer(**self._optimizer_kwargs)  # type: ignore
          perturbation = tf.Variable(
              tf.zeros_like(adv),
              trainable=True,
              constraint=lambda x: tf.clip_by_value(
                  x, -self.delta, self.delta
              ),
          )
  
          for _ in trange(
              self.max_iter,
              desc="Feature Adversaries TensorFlow v2",
              disable=not self.verbose,
          ):
              with tf.GradientTape(
                  watch_accessed_variables=False
              ) as tape:
                  tape.watch(perturbation)
                  adv = x + perturbation
                  loss = loss_fn(x, adv, y)
              gradient = tape.gradient(loss, perturbation)
  
              opt.apply_gradients([(gradient, perturbation)])
  
              if self.estimator.clip_values is not None:
                  adv = tf.clip_by_value(
                      x + perturbation, *self.estimator.clip_values
                  )
              perturbation.assign(adv - x)
      return adv
  
file_path: adversarial-robustness-toolbox/art/attacks/evasion/feature_adversaries/feature_adversaries_tensorflow.py
imports: import logging
  from typing import TYPE_CHECKING, Optional, Tuple, Union
  import numpy
  from tqdm.auto import trange
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator, NeuralNetworkMixin
label_desc: Use image node_id 2 for calling the FeatureAdversariesTensorFlowV2 obj's underlying member method code with example usage: obj._generate_batch(x, y) and returns: adv, loss