class_docstr: Implementation of SmoothMix training, as introduced in Jeong et al. (2021)
  
  | Paper link: https://arxiv.org/abs/2111.09277
class_docstr_tok: ["Implementation","of","SmoothMix","training",",","as","introduced","in","Jeong","et","al",".","(","2021",")","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/2111.09277"]
docstr: The authors' implementation of the SmoothMixPGD attack.
  Code modified from https://github.com/jh-jeong/smoothmix/blob/main/code/train.py
  
  :param inputs: The batch inputs
  :param labels: The batch labels for the inputs
  :param noises: The noise applied to each input in the attack
docstr_tok: ["The","authors","'","implementation","of","the","SmoothMixPGD","attack",".","Code","modified","from","https",":","\/\/github.com\/jh-jeong\/smoothmix\/blob\/main\/code\/train.py",":","param","inputs",":","The","batch","inputs",":","param","labels",":","The","batch","labels","for","the","inputs",":","param","noises",":","The","noise","applied","to","each","input","in","the","attack"]
code: def _smooth_mix_pgd_attack(
      self,
      inputs: "torch.Tensor",
      labels: "torch.Tensor",
      noises: List["torch.Tensor"],
      warmup_v: float,
  ) -> Tuple["torch.Tensor", "torch.Tensor"]:
      """
      The authors' implementation of the SmoothMixPGD attack.
      Code modified from https://github.com/jh-jeong/smoothmix/blob/main/code/train.py
  
      :param inputs: The batch inputs
      :param labels: The batch labels for the inputs
      :param noises: The noise applied to each input in the attack
      """
      import torch
      import torch.nn.functional as F
  
      def _batch_l2_norm(x: torch.Tensor) -> torch.Tensor:
          """
          Perform a batch L2 norm
  
          :param x: The inputs to compute the batch L2 norm of
          """
          x_flat = x.reshape(x.size(0), -1)
          return torch.norm(x_flat, dim=1)
  
      def _project(
          x: torch.Tensor,
          x_0: torch.Tensor,
          maxnorm: Optional[float] = None,
      ):
          """
          Apply a projection of the current inputs with the maxnorm
  
          :param x: The inputs to apply a projection on (either original or adversarial)
          :param x_0: The unperterbed inputs to apply the projection on
          :param maxnorm: The maxnorm value to apply to x
          """
          if maxnorm is not None:
              eta = x - x_0
              eta = eta.renorm(p=2, dim=0, maxnorm=maxnorm)
              x = x_0 + eta
          x = torch.clamp(x, 0, 1)
          x = x.detach()
          return x
  
      adv = inputs.detach()
      init = inputs.detach()
      for i in range(self.num_steps):
          if i == self.mix_step:
              init = adv.detach()
          adv.requires_grad_()
  
          softmax = [
              F.softmax(self._model(adv + noise)[-1], dim=1)
              for noise in noises
          ]
          avg_softmax = torch.mean(torch.stack(softmax), dim=0)
          log_softmax = torch.log(avg_softmax.clamp(min=1e-20))
          loss = F.nll_loss(log_softmax, labels, reduction="sum")
  
          grad = torch.autograd.grad(loss, [adv])[0]
          grad_norm = _batch_l2_norm(grad).view(-1, 1, 1, 1)
          grad = grad / (grad_norm + 1e-8)
          adv = adv + self.alpha * grad
  
          adv = _project(adv, inputs, self.maxnorm)
  
      if self.maxnorm_s is None:
          maxnorm_s = self.alpha * self.mix_step * warmup_v
      else:
          maxnorm_s = self.maxnorm_s * warmup_v
      init = _project(init, inputs, maxnorm_s)
  
      return init, adv
  
file_path: adversarial-robustness-toolbox/art/estimators/certification/randomized_smoothing/smooth_mix/pytorch.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import List, Optional, Tuple, Union, TYPE_CHECKING
  from tqdm.auto import trange
  import numpy
  from art.estimators.certification.randomized_smoothing.pytorch import PyTorchRandomizedSmoothing
  from art.utils import check_and_transform_label_format
label_desc: Use image node_id 3 for calling the PyTorchSmoothMix obj's underlying member method code with example usage: obj._smooth_mix_pgd_attack(inputs, labels, noises, warmup_v) and returns: init,  adv, torch, x