class_docstr: The Momentum Iterative Attack (Dong et al. 2017).
  
  The attack performs nb_iter steps of size eps_iter, while always staying
  within eps from the initial point. The optimization is performed with
  momentum.
  Paper: https://arxiv.org/pdf/1710.06081.pdf
  
  :param predict: forward pass function.
  :param loss_fn: loss function.
  :param eps: maximum distortion.
  :param nb_iter: number of iterations
  :param decay_factor: momentum decay factor.
  :param eps_iter: attack step size.
  :param clip_min: mininum value per input dimension.
  :param clip_max: maximum value per input dimension.
  :param targeted: if the attack is targeted.
  :param ord: the order of maximum distortion (inf or 2).
class_docstr_tok: ["The","Momentum","Iterative","Attack","(","Dong","et","al",".","2017",")",".","The","attack","performs","nb_iter","steps","of","size","eps_iter",",","while","always","staying","within","eps","from","the","initial","point",".","The","optimization","is","performed","with","momentum",".","Paper",":","https",":","\/\/arxiv.org\/pdf\/1710.06081.pdf",":","param","predict",":","forward","pass","function",".",":","param","loss_fn",":","loss","function",".",":","param","eps",":","maximum","distortion",".",":","param","nb_iter",":","number","of","iterations",":","param","decay_factor",":","momentum","decay","factor",".",":","param","eps_iter",":","attack","step","size",".",":","param","clip_min",":","mininum","value","per","input","dimension",".",":","param","clip_max",":","maximum","value","per","input","dimension",".",":","param","targeted",":","if","the","attack","is","targeted",".",":","param","ord",":","the","order","of","maximum","distortion","(","inf","or","2",")","."]
docstr: Given examples (x, y), returns their adversarial counterparts with
  an attack length of eps.
  
  :param x: input tensor.
  :param y: label tensor.
            - if None and self.targeted=False, compute y as predicted
              labels.
            - if self.targeted=True, then y must be the targeted labels.
  :return: tensor containing perturbed inputs.
docstr_tok: ["Given","examples","(","x",",","y",")",",","returns","their","adversarial","counterparts","with","an","attack","length","of","eps",".",":","param","x",":","input","tensor",".",":","param","y",":","label","tensor",".","-","if","None","and","self.targeted=False",",","compute","y","as","predicted","labels",".","-","if","self.targeted=True",",","then","y","must","be","the","targeted","labels",".",":","return",":","tensor","containing","perturbed","inputs","."]
code: def perturb(self, x, y=None):
      """
      Given examples (x, y), returns their adversarial counterparts with
      an attack length of eps.
  
      :param x: input tensor.
      :param y: label tensor.
                - if None and self.targeted=False, compute y as predicted
                  labels.
                - if self.targeted=True, then y must be the targeted labels.
      :return: tensor containing perturbed inputs.
      """
      x, y = self._verify_and_process_inputs(x, y)
  
      delta = torch.zeros_like(x)
      g = torch.zeros_like(x)
  
      delta = nn.Parameter(delta)
  
      for i in range(self.nb_iter):
          if delta.grad is not None:
              delta.grad.detach_()
              delta.grad.zero_()
  
          imgadv = x + delta
          outputs = self.predict(imgadv)
          loss = self.loss_fn(outputs, y)
          if self.targeted:
              loss = -loss
          loss.backward()
  
          g = self.decay_factor * g + normalize_by_pnorm(
              delta.grad.data, p=1
          )
          # according to the paper it should be .sum(), but in their
          #   implementations (both cleverhans and the link from the paper)
          #   it is .mean(), but actually it shouldn't matter
          if self.ord == np.inf:
              delta.data += batch_multiply(self.eps_iter, torch.sign(g))
              delta.data = batch_clamp(self.eps, delta.data)
              delta.data = (
                  clamp(
                      x + delta.data,
                      min=self.clip_min,
                      max=self.clip_max,
                  )
                  - x
              )
          elif self.ord == 2:
              delta.data += self.eps_iter * normalize_by_pnorm(g, p=2)
              delta.data *= clamp(
                  (
                      self.eps
                      * normalize_by_pnorm(delta.data, p=2)
                      / delta.data
                  ),
                  max=1.0,
              )
              delta.data = (
                  clamp(
                      x + delta.data,
                      min=self.clip_min,
                      max=self.clip_max,
                  )
                  - x
              )
          else:
              error = "Only ord = inf and ord = 2 have been implemented"
              raise NotImplementedError(error)
  
      rval = x + delta.data
      return rval
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals
  import numpy
  import torch
  import torch.nn
  from advertorch.utils import clamp
  from advertorch.utils import normalize_by_pnorm
  from advertorch.utils import clamp_by_pnorm
  from advertorch.utils import is_float_or_torch_tensor
  from advertorch.utils import batch_multiply
  from advertorch.utils import batch_clamp
  from advertorch.utils import replicate_input
  from advertorch.utils import batch_l1_proj
  from .base import Attack
  from .base import LabelMixin
  from .utils import rand_init_delta
label_desc: Use image node_id 2 for calling the MomentumIterativeAttack obj's underlying member method code with example usage: obj.perturb(x, y) and returns: rval