class_docstr: DualFormulation is a class that creates the dual objective function
  and access to matrix vector products for the matrix that is constrained
  to be Positive semidefinite
class_docstr_tok: ["DualFormulation","is","a","class","that","creates","the","dual","objective","function","and","access","to","matrix","vector","products","for","the","matrix","that","is","constrained","to","be","Positive","semidefinite"]
docstr: Initializes dual formulation class.
  
  Args:
    sess: Tensorflow session
    dual_var: dictionary of dual variables containing a) lambda_pos
      b) lambda_neg, c) lambda_quad, d) lambda_lu
    neural_net_param_object: NeuralNetParam object created for the network
      under consideration
    test_input: clean example to certify around
    true_class: the class label of the test input
    adv_class: the label that the adversary tried to perturb input to
    input_minval: minimum value of valid input range
    input_maxval: maximum value of valid input range
    epsilon: Size of the perturbation (scaled for [0, 1] input)
    lzs_params: Parameters for Lanczos algorithm (dictionary) in the form:
      {
        'min_iter': 5
        'max_iter': 50
      }
    project_dual: Whether we should create a projected dual object
docstr_tok: ["Initializes","dual","formulation","class",".","Args",":","sess",":","Tensorflow","session","dual_var",":","dictionary","of","dual","variables","containing","a",")","lambda_pos","b",")","lambda_neg",",","c",")","lambda_quad",",","d",")","lambda_lu","neural_net_param_object",":","NeuralNetParam","object","created","for","the","network","under","consideration","test_input",":","clean","example","to","certify","around","true_class",":","the","class","label","of","the","test","input","adv_class",":","the","label","that","the","adversary","tried","to","perturb","input","to","input_minval",":","minimum","value","of","valid","input","range","input_maxval",":","maximum","value","of","valid","input","range","epsilon",":","Size","of","the","perturbation","(","scaled","for","[","0",",","1","]","input",")","lzs_params",":","Parameters","for","Lanczos","algorithm","(","dictionary",")","in","the","form",":","{","'min_iter","'",":","5","'max_iter","'",":","50","}","project_dual",":","Whether","we","should","create","a","projected","dual","object"]
code: def __init__(
      self,
      sess,
      dual_var,
      neural_net_param_object,
      test_input,
      true_class,
      adv_class,
      input_minval,
      input_maxval,
      epsilon,
      lzs_params=None,
      project_dual=True,
  ):
      """Initializes dual formulation class.
  
      Args:
        sess: Tensorflow session
        dual_var: dictionary of dual variables containing a) lambda_pos
          b) lambda_neg, c) lambda_quad, d) lambda_lu
        neural_net_param_object: NeuralNetParam object created for the network
          under consideration
        test_input: clean example to certify around
        true_class: the class label of the test input
        adv_class: the label that the adversary tried to perturb input to
        input_minval: minimum value of valid input range
        input_maxval: maximum value of valid input range
        epsilon: Size of the perturbation (scaled for [0, 1] input)
        lzs_params: Parameters for Lanczos algorithm (dictionary) in the form:
          {
            'min_iter': 5
            'max_iter': 50
          }
        project_dual: Whether we should create a projected dual object
      """
      self.sess = sess
      self.nn_params = neural_net_param_object
      self.test_input = tf.convert_to_tensor(
          test_input, dtype=tf.float32
      )
      self.true_class = true_class
      self.adv_class = adv_class
      self.input_minval = tf.convert_to_tensor(
          input_minval, dtype=tf.float32
      )
      self.input_maxval = tf.convert_to_tensor(
          input_maxval, dtype=tf.float32
      )
      self.epsilon = tf.convert_to_tensor(epsilon, dtype=tf.float32)
      self.lzs_params = lzs_params or DEFAULT_LZS_PARAMS.copy()
      self.final_linear = (
          self.nn_params.final_weights[adv_class, :]
          - self.nn_params.final_weights[true_class, :]
      )
      self.final_linear = tf.reshape(
          self.final_linear, shape=[tf.size(self.final_linear), 1]
      )
      self.final_constant = (
          self.nn_params.final_bias[adv_class]
          - self.nn_params.final_bias[true_class]
      )
      self.lanczos_dtype = tf.float64
      self.nn_dtype = tf.float32
  
      # Computing lower and upper bounds
      # Note that lower and upper are of size nn_params.num_hidden_layers + 1
      self.lower = []
      self.upper = []
  
      # Also computing pre activation lower and upper bounds
      # to compute always-off and always-on units
      self.pre_lower = []
      self.pre_upper = []
  
      # Initializing at the input layer with \ell_\infty constraints
      self.lower.append(
          tf.maximum(self.test_input - self.epsilon, self.input_minval)
      )
      self.upper.append(
          tf.minimum(self.test_input + self.epsilon, self.input_maxval)
      )
      self.pre_lower.append(self.lower[0])
      self.pre_upper.append(self.upper[0])
  
      for i in range(0, self.nn_params.num_hidden_layers):
          lo_plus_up = self.nn_params.forward_pass(
              self.lower[i] + self.upper[i], i
          )
          lo_minus_up = self.nn_params.forward_pass(
              self.lower[i] - self.upper[i], i, is_abs=True
          )
          up_minus_lo = self.nn_params.forward_pass(
              self.upper[i] - self.lower[i], i, is_abs=True
          )
          current_lower = (
              0.5 * (lo_plus_up + lo_minus_up)
              + self.nn_params.biases[i]
          )
          current_upper = (
              0.5 * (lo_plus_up + up_minus_lo)
              + self.nn_params.biases[i]
          )
          self.pre_lower.append(current_lower)
          self.pre_upper.append(current_upper)
          self.lower.append(tf.nn.relu(current_lower))
          self.upper.append(tf.nn.relu(current_upper))
  
      # Run lower and upper because they don't change
      self.pre_lower = self.sess.run(self.pre_lower)
      self.pre_upper = self.sess.run(self.pre_upper)
      self.lower = self.sess.run(self.lower)
      self.upper = self.sess.run(self.upper)
  
      # Using the preactivation lower and upper bounds
      # to compute the linear regions
      self.positive_indices = []
      self.negative_indices = []
      self.switch_indices = []
  
      for i in range(0, self.nn_params.num_hidden_layers + 1):
          # Positive index = 1 if the ReLU is always "on"
          self.positive_indices.append(
              np.asarray(self.pre_lower[i] >= 0, dtype=np.float32)
          )
          # Negative index = 1 if the ReLU is always off
          self.negative_indices.append(
              np.asarray(self.pre_upper[i] <= 0, dtype=np.float32)
          )
          # Switch index = 1 if the ReLU could be either on or off
          self.switch_indices.append(
              np.asarray(
                  np.multiply(self.pre_lower[i], self.pre_upper[i]) < 0,
                  dtype=np.float32,
              )
          )
  
      # Computing the optimization terms
      self.lambda_pos = [x for x in dual_var["lambda_pos"]]
      self.lambda_neg = [x for x in dual_var["lambda_neg"]]
      self.lambda_quad = [x for x in dual_var["lambda_quad"]]
      self.lambda_lu = [x for x in dual_var["lambda_lu"]]
      self.nu = dual_var["nu"]
      self.vector_g = None
      self.scalar_f = None
      self.matrix_h = None
      self.matrix_m = None
      self.matrix_m_dimension = 1 + np.sum(self.nn_params.sizes)
  
      # The primal vector in the SDP can be thought of as [layer_1, layer_2..]
      # In this concatenated version, dual_index[i] that marks the start
      # of layer_i
      # This is useful while computing implicit products with matrix H
      self.dual_index = [0]
      for i in range(self.nn_params.num_hidden_layers + 1):
          self.dual_index.append(
              self.dual_index[-1] + self.nn_params.sizes[i]
          )
  
      # Construct objectives, matrices, and certificate
      self.set_differentiable_objective()
      if not self.nn_params.has_conv:
          self.get_full_psd_matrix()
  
      # Setup Lanczos functionality for compute certificate
      self.construct_lanczos_params()
  
      # Create projected dual object
      if project_dual:
          self.projected_dual = self.create_projected_dual()
  
file_path: cleverhans/cleverhans_v3.1.0/cleverhans/experimental/certification/dual_formulation.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from scipy.sparse.linalg import eigs, LinearOperator
  import tensorflow
  from tensorflow.contrib import autograph
  import numpy
  from cleverhans.experimental.certification import utils
label_desc: Use image node_id 1 to create a new DualFormulation object from inherited base classes: object with example: obj = DualFormulation(sess, dual_var, neural_net_param_object, test_input, true_class, adv_class, input_minval, input_maxval, epsilon, lzs_params, project_dual)