class_docstr: Projected Gradient Descent is an iterative version of the one-step attack
  FGSM that can generate adversarial examples. It takes multiple gradient
  steps to search for an adversarial perturbation within the desired
  neighbor ball around the original inputs. In a non-targeted attack, the
  formulation is::
  
      x_0 = x
      x_(t+1) = Clip_r(x_t + alpha * sign(gradient of L(theta, x, t)))
  
  where Clip denotes the function that projects its argument to the r-neighbor
  ball around x so that the perturbation will be bounded. Alpha is the step
  size. L(theta, x, y) is the model's loss function with respect to model
  parameters, inputs and targets.
  In a targeted attack, the formulation is similar::
  
      x_0 = x
      x_(t+1) = Clip_r(x_t - alpha * sign(gradient of L(theta, x, t)))
  
  More details on Projected Gradient Descent can be found in the original
  paper: https://arxiv.org/abs/1706.06083
docstr: Args:
      forward_func (Callable): The pytorch model for which the attack is
                  computed.
      loss_func (Callable, optional): Loss function of which the gradient
                  computed. The loss function should take in outputs of the
                  model and labels, and return the loss for each input tensor.
                  The default loss function is negative log.
      lower_bound (float, optional): Lower bound of input values.
                  Default: ``float("-inf")``
      upper_bound (float, optional): Upper bound of input values.
                  e.g. image pixels must be in the range 0-255
                  Default: ``float("inf")``
  
  Attributes:
      bound (Callable): A function that bounds the input values based on
                  given lower_bound and upper_bound. Can be overwritten for
                  custom use cases if necessary.
docstr_tok: ["Args",":","forward_func","(","Callable",")",":","The","pytorch","model","for","which","the","attack","is","computed",".","loss_func","(","Callable",",","optional",")",":","Loss","function","of","which","the","gradient","computed",".","The","loss","function","should","take","in","outputs","of","the","model","and","labels",",","and","return","the","loss","for","each","input","tensor",".","The","default","loss","function","is","negative","log",".","lower_bound","(","float",",","optional",")",":","Lower","bound","of","input","values",".","Default",":","``","float","(","``","-inf","''",")","``","upper_bound","(","float",",","optional",")",":","Upper","bound","of","input","values",".","e.g",".","image","pixels","must","be","in","the","range","0-255","Default",":","``","float","(","``","inf","''",")","``","Attributes",":","bound","(","Callable",")",":","A","function","that","bounds","the","input","values","based","on","given","lower_bound","and","upper_bound",".","Can","be","overwritten","for","custom","use","cases","if","necessary","."]
code: def __init__(
      self,
      forward_func: Callable,
      loss_func: Callable = None,
      lower_bound: float = float("-inf"),
      upper_bound: float = float("inf"),
  ) -> None:
      r"""
      Args:
          forward_func (Callable): The pytorch model for which the attack is
                      computed.
          loss_func (Callable, optional): Loss function of which the gradient
                      computed. The loss function should take in outputs of the
                      model and labels, and return the loss for each input tensor.
                      The default loss function is negative log.
          lower_bound (float, optional): Lower bound of input values.
                      Default: ``float("-inf")``
          upper_bound (float, optional): Upper bound of input values.
                      e.g. image pixels must be in the range 0-255
                      Default: ``float("inf")``
  
      Attributes:
          bound (Callable): A function that bounds the input values based on
                      given lower_bound and upper_bound. Can be overwritten for
                      custom use cases if necessary.
      """
      super().__init__()
      self.forward_func = forward_func
      self.fgsm = FGSM(forward_func, loss_func)
      self.bound = lambda x: torch.clamp(
          x, min=lower_bound, max=upper_bound
      )
  
file_path: captum/captum/robust/_core/pgd.py
imports: from typing import Any, Callable, Optional, Tuple, Union
  import torch
  import torch.nn.functional
  from captum._utils.common import _format_output, _format_tensor_into_tuples, _is_tuple
  from captum._utils.typing import TensorOrTupleOfTensorsGeneric
  from captum.log import log_usage
  from captum.robust._core.fgsm import FGSM
  from captum.robust._core.perturbation import Perturbation
  from torch import Tensor
label_desc: Use image node_id 1 to create a new PGD object from inherited base classes: Perturbation with example: obj = PGD(forward_func, loss_func, lower_bound, upper_bound)