class_docstr: The Projected Gradient Descent attack is an iterative method in which, after each iteration, the perturbation is
  projected on an lp-ball of specified radius (in addition to clipping the values of the adversarial sample so that it
  lies in the permitted data range). This is the attack proposed by Madry et al. for adversarial training.
  
  | Paper link: https://arxiv.org/abs/1706.06083
class_docstr_tok: ["The","Projected","Gradient","Descent","attack","is","an","iterative","method","in","which",",","after","each","iteration",",","the","perturbation","is","projected","on","an","lp-ball","of","specified","radius","(","in","addition","to","clipping","the","values","of","the","adversarial","sample","so","that","it","lies","in","the","permitted","data","range",")",".","This","is","the","attack","proposed","by","Madry","et","al",".","for","adversarial","training",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1706.06083"]
docstr: Project `values` on the L_p norm ball of size `eps`.
  
  :param values: Values to clip.
  :param eps: Maximum norm allowed.
  :param norm_p: L_p norm to use for clipping supporting 1, 2 and `np.Inf`.
  :return: Values of `values` after projection.
docstr_tok: ["Project","`","values","`","on","the","L_p","norm","ball","of","size","`","eps","`",".",":","param","values",":","Values","to","clip",".",":","param","eps",":","Maximum","norm","allowed",".",":","param","norm_p",":","L_p","norm","to","use","for","clipping","supporting","1",",","2","and","`","np.Inf","`",".",":","return",":","Values","of","`","values","`","after","projection","."]
code: def _projection(
      values: "tf.Tensor",
      eps: Union[int, float, np.ndarray],
      norm_p: Union[int, float, str],
  ) -> "tf.Tensor":
      """
      Project `values` on the L_p norm ball of size `eps`.
  
      :param values: Values to clip.
      :param eps: Maximum norm allowed.
      :param norm_p: L_p norm to use for clipping supporting 1, 2 and `np.Inf`.
      :return: Values of `values` after projection.
      """
      import tensorflow as tf
  
      # Pick a small scalar to avoid division by 0
      tol = 10e-8
      values_tmp = tf.reshape(values, (values.shape[0], -1))
  
      if norm_p == 2:
          if isinstance(eps, np.ndarray):
              raise NotImplementedError(
                  "The parameter `eps` of type `np.ndarray` is not supported to use with norm 2."
              )
  
          values_tmp = values_tmp * tf.expand_dims(
              tf.minimum(
                  1.0, eps / (tf.norm(values_tmp, ord=2, axis=1) + tol)
              ),
              axis=1,
          )
  
      elif norm_p == 1:
          if isinstance(eps, np.ndarray):
              raise NotImplementedError(
                  "The parameter `eps` of type `np.ndarray` is not supported to use with norm 1."
              )
  
          values_tmp = values_tmp * tf.expand_dims(
              tf.minimum(
                  1.0, eps / (tf.norm(values_tmp, ord=1, axis=1) + tol)
              ),
              axis=1,
          )
  
      elif norm_p in ["inf", np.inf]:
          if isinstance(eps, np.ndarray):
              eps = eps * np.ones(shape=values.shape)
              eps = eps.reshape([eps.shape[0], -1])  # type: ignore
  
          values_tmp = tf.sign(values_tmp) * tf.minimum(
              tf.math.abs(values_tmp), eps
          )
  
      else:
          raise NotImplementedError(
              'Values of `norm_p` different from 1, 2 "inf" and `np.inf` are currently not supported.'
          )
  
      values = tf.reshape(values_tmp, values.shape)
  
      return values
  
file_path: adversarial-robustness-toolbox/art/attacks/evasion/projected_gradient_descent/projected_gradient_descent_tensorflow_v2.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Union, TYPE_CHECKING
  import numpy
  from tqdm.auto import tqdm
  from art.config import ART_NUMPY_DTYPE
  from art.estimators.estimator import BaseEstimator, LossGradientsMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.attacks.evasion.projected_gradient_descent.projected_gradient_descent_numpy import ProjectedGradientDescentCommon
  from art.utils import compute_success, random_sphere, compute_success_array
  from art.summary_writer import SummaryWriter
label_desc: Use image node_id 7 for calling the ProjectedGradientDescentTensorFlowV2 obj's underlying member method code with example usage: obj._projection(values, eps, norm_p) and returns: values