class_docstr: Return a tensor that constructs adversarial examples for the given
  input. Generate uses tf.py_func in order to operate over tensors.
  :param sess: a TF session.
  :param x: A tensor with the inputs.
  :param logits: A tensor with model's output logits.
  :param targeted_label: A tensor with the target labels.
  :param binary_search_steps: The number of times we perform binary
                              search to find the optimal tradeoff-
                              constant between norm of the purturbation
                              and cross-entropy loss of classification.
  :param max_iterations: The maximum number of iterations.
  :param initial_const: The initial tradeoff-constant to use to tune the
                        relative importance of size of the purturbation
                        and cross-entropy loss of the classification.
  :param clip_min: Minimum input component value
  :param clip_max: Maximum input component value
  :param num_labels: The number of classes in the model's output.
  :param batch_size: Number of attacks to run simultaneously.
docstr: Perform the attack on the given instance for the given targets.
docstr_tok: ["Perform","the","attack","on","the","given","instance","for","the","given","targets","."]
code: def attack(self, x_val, targets):
      """
      Perform the attack on the given instance for the given targets.
      """
  
      def lbfgs_objective(adv_x, self, targets, oimgs, CONST):
          """returns the function value and the gradient for fmin_l_bfgs_b"""
          loss = self.sess.run(
              self.loss,
              feed_dict={
                  self.x: adv_x.reshape(oimgs.shape),
                  self.targeted_label: targets,
                  self.ori_img: oimgs,
                  self.const: CONST,
              },
          )
          grad = self.sess.run(
              self.grad,
              feed_dict={
                  self.x: adv_x.reshape(oimgs.shape),
                  self.targeted_label: targets,
                  self.ori_img: oimgs,
                  self.const: CONST,
              },
          )
          return loss, grad.flatten().astype(float)
  
      def attack_success(out, target, targeted_attack):
          """returns attack result"""
          if targeted_attack:
              return out == target
          else:
              return out != target
  
      # begin the main part for the attack
      from scipy.optimize import fmin_l_bfgs_b
  
      oimgs = np.clip(x_val, self.clip_min, self.clip_max)
      CONST = np.ones(self.batch_size) * self.initial_const
  
      # set the lower and upper bounds accordingly
      lower_bound = np.zeros(self.batch_size)
      upper_bound = np.ones(self.batch_size) * 1e10
  
      # set the box constraints for the optimization function
      clip_min = self.clip_min * np.ones(oimgs.shape[:])
      clip_max = self.clip_max * np.ones(oimgs.shape[:])
      clip_bound = list(zip(clip_min.flatten(), clip_max.flatten()))
  
      # placeholders for the best l2 and instance attack found so far
      o_bestl2 = [1e10] * self.batch_size
      o_bestattack = np.copy(oimgs)
  
      for outer_step in range(self.binary_search_steps):
          _logger.debug(
              "  Binary search step %s of %s",
              outer_step,
              self.binary_search_steps,
          )
  
          # The last iteration (if we run many steps) repeat the search once.
          if self.repeat and outer_step == self.binary_search_steps - 1:
              CONST = upper_bound
  
          # optimization function
          adv_x, _, __ = fmin_l_bfgs_b(
              lbfgs_objective,
              oimgs.flatten().astype(float),
              args=(self, targets, oimgs, CONST),
              bounds=clip_bound,
              maxiter=self.max_iterations,
              iprint=0,
          )
  
          adv_x = adv_x.reshape(oimgs.shape)
          assert (
              np.amax(adv_x) <= self.clip_max
              and np.amin(adv_x) >= self.clip_min
          ), "fmin_l_bfgs_b returns are invalid"
  
          # adjust the best result (i.e., the adversarial example with the
          # smallest perturbation in terms of L_2 norm) found so far
          preds = np.atleast_1d(
              utils_tf.model_argmax(
                  self.sess, self.x, self.logits, adv_x
              )
          )
          _logger.debug("predicted labels are %s", preds)
  
          l2s = np.zeros(self.batch_size)
          for i in range(self.batch_size):
              l2s[i] = np.sum(np.square(adv_x[i] - oimgs[i]))
  
          for e, (l2, pred, ii) in enumerate(zip(l2s, preds, adv_x)):
              if l2 < o_bestl2[e] and attack_success(
                  pred, np.argmax(targets[e]), self.targeted_attack
              ):
                  o_bestl2[e] = l2
                  o_bestattack[e] = ii
  
          # adjust the constant as needed
          for e in range(self.batch_size):
              if attack_success(
                  preds[e], np.argmax(targets[e]), self.targeted_attack
              ):
                  # success, divide const by two
                  upper_bound[e] = min(upper_bound[e], CONST[e])
                  if upper_bound[e] < 1e9:
                      CONST[e] = (lower_bound[e] + upper_bound[e]) / 2
              else:
                  # failure, either multiply by 10 if no solution found yet
                  #          or do binary search with the known upper bound
                  lower_bound[e] = max(lower_bound[e], CONST[e])
                  if upper_bound[e] < 1e9:
                      CONST[e] = (lower_bound[e] + upper_bound[e]) / 2
                  else:
                      CONST[e] *= 10
  
          _logger.debug(
              "  Successfully generated adversarial examples "
              "on %s of %s instances.",
              sum(upper_bound < 1e9),
              self.batch_size,
          )
          o_bestl2 = np.array(o_bestl2)
          mean = np.mean(np.sqrt(o_bestl2[o_bestl2 < 1e9]))
          _logger.debug(
              "   Mean successful distortion: {:.4g}".format(mean)
          )
  
      # return the best solution found
      o_bestl2 = np.array(o_bestl2)
      return o_bestattack
  
file_path: cleverhans/cleverhans_v3.1.0/cleverhans/attacks/lbfgs.py
imports: import numpy
  import tensorflow
  from cleverhans.attacks.attack import Attack
  from cleverhans.compat import reduce_sum, softmax_cross_entropy_with_logits
  from cleverhans.model import CallableModelWrapper, Model, wrapper_warning
  from cleverhans import utils
  from cleverhans import utils_tf
label_desc: Use image node_id 2 for calling the LBFGS_impl obj's underlying member method code with example usage: obj.attack(x_val, targets) and returns: o_bestattack, loss,  grad, unknown, unknown