<commit_before>"""The CarliniWagnerL2 attack.
"""
import numpy as np
import tensorflow as tf
from cleverhans.future.tf2.utils_tf import get_or_guess_labels, set_with_mask


def carlini_wagner_l2(model_fn, x, **kwargs):
  """
  This is the function interface for the Carlini-Wagner-L2 attack.
  For more details on the attack and the parameters see the corresponding class.
  """
  return CarliniWagnerL2(model_fn, **kwargs).attack(x)


class CarliniWagnerL2(object):
  def __init__(self,
               model_fn,
               y=None,
               targeted=False,
               batch_size=128,
               clip_min=0.,
               clip_max=1.,
               binary_search_steps=5,
               max_iterations=1_000,
               abort_early=True,
               confidence=0.,
               initial_const=1e-2,
               learning_rate=5e-3):
    """
    This attack was originally proposed by <NAME> Wagner. It is an
    iterative attack that finds adversarial examples on many defenses that
    are robust to other attacks.
    Paper link: https://arxiv.org/abs/1608.04644
    At a high level, this attack is an iterative attack using Adam and
    a specially-chosen loss function to find adversarial examples with
    lower distortion than other attacks. This comes at the cost of speed,
    as this attack is often much slower than others.

    :param model_fn: a callable that takes an input tensor and returns the model logits.
    :param y: (optional) Tensor with target labels. 
    :param targeted: (optional) Targeted attack? 
    :param batch_size (optional): Number of attacks to run simultaneously.
    :param clip_min: (optional) float. Minimum float values for adversarial example components.
    :param clip_max: (optional) float. Maximum float value for adversarial example components.
    :param binary_search_steps (optional): The number of times we perform binary
                            search to find the optimal tradeoff-
                            constant between norm of the purturbation
                            and confidence of the classification.
    :param max_iterations (optional): The maximum number of iterations. Setting this
                           to a larger value will produce lower distortion
                           results. Using only a few iterations requires
                           a larger learning rate, and will produce larger
                           distortion results.
    :param abort_early (optional): If true, allows early aborts if gradient descent
                    is unable to make progress (i.e., gets stuck in
                    a local minimum).
    :param confidence (optional): Confidence of adversarial examples: higher produces
                       examples with larger l2 distortion, but more
                       strongly classified as adversarial.
    :param initial_const (optional): The initial tradeoff-constant used to tune the
                      relative importance of the size of the perturbation
                      and confidence of classification.
                      If binary_search_steps is large, the initial
                      constant is not important. A smaller value of
                      this constant gives lower distortion results.
    :param learning_rate (optional): The learning rate for the attack algorithm.
                      Smaller values produce better results but are
                      slower to converge.
    """
    self.model_fn = model_fn

    self.batch_size = batch_size

    self.y = y
    self.targeted = y is not None

    self.clip_min = clip_min
    self.clip_max = clip_max

    self.binary_search_steps = binary_search_steps
    self.max_iterations = max_iterations
    self.abort_early = abort_early
    self.learning_rate = learning_rate

    self.confidence = confidence
    self.initial_const = initial_const

    # the optimizer
    self.optimizer = tf.keras.optimizers.Adam(self.learning_rate)

    super(CarliniWagnerL2, self).__init__()

  def attack(self, x):
    """
    Returns adversarial examples for the tensor.
    :param x: input tensor.
    :return: a numpy tensor with the adversarial example.
    """
    adv_ex = np.zeros_like(x)
    for i in range(0, len(x), self.batch_size):
      adv_ex[i:i +
             self.batch_size] = self._attack(x[i:i+self.batch_size]).numpy()

    return adv_ex

  def _attack(self, x):
    if self.clip_min is not None:
      assert np.all(tf.math.greater_equal(x, self.clip_min))

    if self.clip_max is not None:
      assert np.all(tf.math.less_equal(x, self.clip_max))

    y, _ = get_or_guess_labels(
        self.model_fn, x, y=self.y, targeted=self.targeted)

    # cast to tensor if provided as numpy array
    original_x = tf.cast(x, tf.float32)
    shape = original_x.shape

    assert y.shape.as_list()[0] == original_x.shape.as_list()[0]

    # re-scale x to [0, 1]
    x = original_x
    x = (x - self.clip_min) / (self.clip_max - self.clip_min)
    x = tf.clip_by_value(x, 0., 1.)

    # scale to [-1, 1]
    x = (x * 2.) - 1.

    # convert tonh-space
    x = tf.atanh(x * .999999)<commit_msg>Custom exception instead of asserts<commit_after>"""The CarliniWagnerL2 attack.
"""
import numpy as np
import tensorflow as tf
from cleverhans.tf2.utils import get_or_guess_labels, set_with_mask


def carlini_wagner_l2(model_fn, x, **kwargs):
  """
  This is the function interface for the Carlini-Wagner-L2 attack.
  For more details on the attack and the parameters see the corresponding class.
  """
  return CarliniWagnerL2(model_fn, **kwargs).attack(x)


class CarliniWagnerL2Exception(Exception):
  pass


class CarliniWagnerL2(object):
  def __init__(self,
               model_fn,
               y=None,
               targeted=False,
               batch_size=128,
               clip_min=0.,
               clip_max=1.,
               binary_search_steps=5,
               max_iterations=1_000,
               abort_early=True,
               confidence=0.,
               initial_const=1e-2,
               learning_rate=5e-3):
    """
    This attack was originally proposed by <NAME> Wagner. It is an
    iterative attack that finds adversarial examples on many defenses that
    are robust to other attacks.
    Paper link: https://arxiv.org/abs/1608.04644
    At a high level, this attack is an iterative attack using Adam and
    a specially-chosen loss function to find adversarial examples with
    lower distortion than other attacks. This comes at the cost of speed,
    as this attack is often much slower than others.

    :param model_fn: a callable that takes an input tensor and returns the model logits.
    :param y: (optional) Tensor with target labels. 
    :param targeted: (optional) Targeted attack? 
    :param batch_size (optional): Number of attacks to run simultaneously.
    :param clip_min: (optional) float. Minimum float values for adversarial example components.
    :param clip_max: (optional) float. Maximum float value for adversarial example components.
    :param binary_search_steps (optional): The number of times we perform binary
                            search to find the optimal tradeoff-
                            constant between norm of the purturbation
                            and confidence of the classification.
    :param max_iterations (optional): The maximum number of iterations. Setting this
                           to a larger value will produce lower distortion
                           results. Using only a few iterations requires
                           a larger learning rate, and will produce larger
                           distortion results.
    :param abort_early (optional): If true, allows early aborts if gradient descent
                    is unable to make progress (i.e., gets stuck in
                    a local minimum).
    :param confidence (optional): Confidence of adversarial examples: higher produces
                       examples with larger l2 distortion, but more
                       strongly classified as adversarial.
    :param initial_const (optional): The initial tradeoff-constant used to tune the
                      relative importance of the size of the perturbation
                      and confidence of classification.
                      If binary_search_steps is large, the initial
                      constant is not important. A smaller value of
                      this constant gives lower distortion results.
    :param learning_rate (optional): The learning rate for the attack algorithm.
                      Smaller values produce better results but are
                      slower to converge.
    """
    self.model_fn = model_fn

    self.batch_size = batch_size

    self.y = y
    self.targeted = y is not None

    self.clip_min = clip_min
    self.clip_max = clip_max

    self.binary_search_steps = binary_search_steps
    self.max_iterations = max_iterations
    self.abort_early = abort_early
    self.learning_rate = learning_rate

    self.confidence = confidence
    self.initial_const = initial_const

    # the optimizer
    self.optimizer = tf.keras.optimizers.Adam(self.learning_rate)

    super(CarliniWagnerL2, self).__init__()

  def attack(self, x):
    """
    Returns adversarial examples for the tensor.
    :param x: input tensor.
    :return: a numpy tensor with the adversarial example.
    """
    adv_ex = np.zeros_like(x)
    for i in range(0, len(x), self.batch_size):
      adv_ex[i:i +
             self.batch_size] = self._attack(x[i:i+self.batch_size]).numpy()

    return adv_ex

  def _attack(self, x):
    if self.clip_min is not None:
      if not np.all(tf.math.greater_equal(x, self.clip_min)):
        raise CarliniWagnerL2Exception(
            f"The input is smaller than the minimum value of {self.clip_min}r")

    if self.clip_max is not None:
      if not np.all(tf.math.less_equal(x, self.clip_max)):
        raise CarliniWagnerL2Exception(
            f"The input is greater than the maximum value of {self.clip_max}!")

    y, _ = get_or_guess_labels(
        self.model_fn, x, y=self.y, targeted=self.targeted)

    # cast to tensor if provided as numpy array
    original_x = tf.cast(x, tf.float32)
    shape = original_x.shape

    if not y.shape.as_list()[0] == original_x.shape.as_list()[0]:
      raise CarliniWagnerL2Exception(
          "x and y do not have the same shape!")

    # re-scale x to [0, 1]
    x = original_x
    x = (x - self.clip_min) / (self.clip_max - self.clip_min)
    x = tf.clip_by_value(x, 0., 1.)

    # scale to [-1, 1]
    x = (x * 2.) - 1.

    # convert tonh-space
    x = tf.atanh(x * .999999)
{'fraction_non_alphanumeric': 0.07055847076461769, 'fraction_numerical': 0.009932533733133433, 'mean_word_length': 2.2689127105666156, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '516983', 'n_tokens_mistral': 3049, 'n_tokens_neox': 2871, 'n_words': 1032}