class_docstr: Implementation of the adversarial patch attack for square and rectangular images and videos in Numpy.
  
  | Paper link: https://arxiv.org/abs/1712.09665
class_docstr_tok: ["Implementation","of","the","adversarial","patch","attack","for","square","and","rectangular","images","and","videos","in","Numpy",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1712.09665"]
code: def _random_transformation(self, patch, scale, mask_2d):
      patch_mask = self._get_circular_patch_mask()
      transformation = {}
  
      if self.nb_dims == 4:
          patch = np.expand_dims(patch, axis=0)
          patch = np.repeat(
              patch, axis=0, repeats=self.input_shape[0]
          ).astype(np.float32)
  
      # rotate
      angle = random.uniform(-self.rotation_max, self.rotation_max)
      transformation["rotate"] = angle
      patch = self._rotate(patch, angle)
      patch_mask = self._rotate(patch_mask, angle)
  
      # scale
      if scale is None:
          scale = random.uniform(self.scale_min, self.scale_max)
      patch = self._scale(patch, scale)
      patch_mask = self._scale(patch_mask, scale)
      transformation["scale"] = scale
  
      # pad
      pad_h_before = int(
          (self.input_shape[self.i_h] - patch.shape[self.i_h]) / 2
      )
      pad_h_after = int(
          self.input_shape[self.i_h]
          - pad_h_before
          - patch.shape[self.i_h]
      )
  
      pad_w_before = int(
          (self.input_shape[self.i_w] - patch.shape[self.i_w]) / 2
      )
      pad_w_after = int(
          self.input_shape[self.i_w]
          - pad_w_before
          - patch.shape[self.i_w]
      )
  
      if self.estimator.channels_first:
          if self.nb_dims == 3:
              pad_width = ((0, 0), (pad_h_before, pad_h_after), (pad_w_before, pad_w_after))  # type: ignore
          elif self.nb_dims == 4:
              pad_width = ((0, 0), (0, 0), (pad_h_before, pad_h_after), (pad_w_before, pad_w_after))  # type: ignore
      else:
          if self.nb_dims == 3:
              pad_width = ((pad_h_before, pad_h_after), (pad_w_before, pad_w_after), (0, 0))  # type: ignore
          elif self.nb_dims == 4:
              pad_width = ((0, 0), (pad_h_before, pad_h_after), (pad_w_before, pad_w_after), (0, 0))  # type: ignore
  
      transformation["pad_h_before"] = pad_h_before
      transformation["pad_w_before"] = pad_w_before
  
      patch = np.pad(
          patch,
          pad_width=pad_width,
          mode="constant",
          constant_values=(0, 0),
      )
      patch_mask = np.pad(
          patch_mask,
          pad_width=pad_width,
          mode="constant",
          constant_values=(0, 0),
      )
  
      # shift
      if mask_2d is None:
          shift_max_h = (
              self.input_shape[self.i_h]
              - self.patch_shape[self.i_h] * scale
          ) / 2.0
          shift_max_w = (
              self.input_shape[self.i_w]
              - self.patch_shape[self.i_w] * scale
          ) / 2.0
          if shift_max_h > 0 and shift_max_w > 0:
              shift_h = random.uniform(-shift_max_h, shift_max_h)
              shift_w = random.uniform(-shift_max_w, shift_max_w)
              patch = self._shift(patch, shift_h, shift_w)
              patch_mask = self._shift(patch_mask, shift_h, shift_w)
          else:
              shift_h = 0
              shift_w = 0
      else:
          edge_x_0 = int(self.patch_shape[self.i_h] * scale) // 2
          edge_x_1 = int(self.patch_shape[self.i_h] * scale) - edge_x_0
          edge_y_0 = int(self.patch_shape[self.i_w] * scale) // 2
          edge_y_1 = int(self.patch_shape[self.i_w] * scale) - edge_y_0
  
          mask_2d[0:edge_x_0, :] = False
          mask_2d[-edge_x_1:, :] = False
          mask_2d[:, 0:edge_y_0] = False
          mask_2d[:, -edge_y_1:] = False
  
          num_pos = np.argwhere(mask_2d).shape[0]
          pos_id = np.random.choice(num_pos, size=1)
          pos = np.argwhere(mask_2d)[pos_id[0]]
          shift_h = pos[0] - (self.input_shape[self.i_h]) / 2.0
          shift_w = pos[1] - (self.input_shape[self.i_w]) / 2.0
  
          patch = self._shift(patch, shift_h, shift_w)
          patch_mask = self._shift(patch_mask, shift_h, shift_w)
  
      transformation["shift_h"] = shift_h
      transformation["shift_w"] = shift_w
  
      return patch, patch_mask, transformation
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  import math
  from typing import Optional, Union, Tuple, TYPE_CHECKING
  import random
  import numpy
  from scipy.ndimage import rotate, shift, zoom
  from tqdm.auto import trange
  from art.attacks.attack import EvasionAttack
  from art.attacks.evasion.adversarial_patch.utils import insert_transformed_patch
  from art.estimators.estimator import BaseEstimator, NeuralNetworkMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.utils import check_and_transform_label_format
label_desc: Use image node_id 10 for calling the AdversarialPatchNumpy obj's underlying member method code with example usage: obj._random_transformation(patch, scale, mask_2d) and returns: patch,  patch_mask,  transformation