Exemplo n.º 1
0
 def init_q(self):
     q_targets = self.get_q_target()
     q_predictions = self.q_net(self.states_ph)
     batch_size = tf_v1.shape(self.actions_ph)[0]
     indices = tf_v1.stack([tf_v1.range(batch_size), self.actions_ph],
                           axis=-1)
     # From the q_predictions, only change the Q values of given action index to the target value
     q_targets = tf_v1.tensor_scatter_nd_update(q_predictions, indices,
                                                q_targets)
     q_loss = tf_v1.losses.mean_squared_error(labels=q_targets,
                                              predictions=q_predictions)
     optimizer = tf_v1.train.AdamOptimizer(learning_rate=self.lr_ph)
     train_op = get_clipped_train_op(q_loss,
                                     optimizer=optimizer,
                                     var_list=self.q_net.trainable_vars,
                                     clip_norm=self.clip_norm)
     self.q_net.setup_loss(q_loss, train_op)
Exemplo n.º 2
0
    def __init__(self, model, epsilon, loss_func):
        # Arguements
        self.epsilon = epsilon  # maximum perturbation
        self.loss_func = loss_func  # type of loss function (xent for Cross-Entropy loss, cw for Carlini-Wagner loss)

        # Networks
        self.x_input = model.x_input  # a placeholder for image
        self.y_input = model.y_input  # a placeholder for label
        self.logits = model.logits  # unnormalized logits

        ####################################################################
        # TODO: Implement Cross-Entropy loss and Carlini-Wagner loss.      #
        # For Carlini-Wagner loss, set the confidence of hinge loss to 50. #
        # Be careful about the sign of loss.                               #
        ####################################################################

        C = tf.reduce_max(self.y_input)
        sh = tf.shape(self.x_input)
        # If loss function is Cross-Entropy loss
        if self.loss_func == 'xent':
            self.losses = tf.nn.softmax_cross_entropy_with_logits(
                labels=tf.one_hot(self.y_input, 10), logits=self.logits)
        # If loss function is Carlini-Wagner loss
        elif self.loss_func == 'cw':
            correct_logits = tf.gather_nd(
                self.logits, tf.stack([tf.range(sh[0]), self.y_input], axis=1))

            copy = tf.identity(self.logits)

            copy = tf.tensor_scatter_nd_update(
                copy, tf.stack([tf.range(sh[0]), self.y_input], axis=1),
                tf.zeros(sh[0]))

            max_logits = tf.reduce_max(copy, axis=1)

            #print(self.logits, max_logits, correct_logits)
            self.losses = tf.maximum(max_logits - correct_logits, -50)
        else:
            print('Loss function must be xent or cw')
            sys.exit()

        ###########################################################################################################
        # TODO: Define a tensor whose value represents the gradient of loss function with respect to input image. #
        ###########################################################################################################

        self.gradients = tf.gradients(self.losses, [self.x_input])
Exemplo n.º 3
0
    def __init__(self, model, epsilon, step_size, num_steps, loss_func):
        # Arguements
        self.epsilon = epsilon  # maximum perturbation
        self.step_size = step_size  # step size per iteration
        self.num_steps = num_steps  # the number of iterations
        self.loss_func = loss_func  # type of loss function (xent for Cross-Entropy loss, cw for Carlini-Wagner loss)

        # Networks
        self.x_input = model.x_input  # a placeholder for image
        self.y_input = model.y_input  # a placeholder for label
        self.logits = model.logits  # unnormalized logits

        # NES
        self.nes_batch_size = 50  # number of vectors to sample for NES estimation
        self.sigma = 0.25  # noise scale variable for NES estimation

        ##################################################################################
        # TODO: Implement Cross-Entropy loss and Carlini-Wagner loss.                    #
        # For Carlini-Wagner loss, set the confidence of hinge loss to 50.               #
        # Be careful about the sign of the loss.                                         #
        # You may use the same implementation from FGSM!                                 #
        ##################################################################################

        # If loss function is Cross-Entropy loss
        if self.loss_func == 'xent':
            self.losses = tf.nn.softmax_cross_entropy_with_logits_v2(
                labels=tf.one_hot(self.y_input, 10), logits=self.logits)

        # If loss function is Carlini-Wagner loss
        elif self.loss_func == 'cw':
            correct_logits = tf.gather_nd(
                self.logits, tf.stack([tf.range(sh[0]), self.y_input], axis=1))

            copy = tf.identity(self.logits)

            copy = tf.tensor_scatter_nd_update(
                copy, tf.stack([tf.range(sh[0]), self.y_input], axis=1),
                tf.zeros(sh[0]))

            max_logits = tf.reduce_max(copy, axis=1)

            self.losses = tf.maximum(max_logits - correct_logits, -50)
        else:
            print('Loss function must be xent or cw')
            sys.exit()
Exemplo n.º 4
0
 def init_q(self):
     q_targets = self.get_q_target()
     batch_size = tf_v1.shape(self.actions_ph)[0]
     indices = tf_v1.stack([tf_v1.range(batch_size), self.actions_ph],
                           axis=-1)
     q_predictions = self.q_net(self.states_ph)
     q_targets = tf_v1.tensor_scatter_nd_update(q_predictions, indices,
                                                q_targets)
     # q_predictions = tf_v1.gather_nd(q_predictions, indices)
     # q_loss = tf_v1.reduce_mean(tf_v1.losses.huber_loss(labels=q_targets, predictions=q_predictions))
     q_loss = tf_v1.losses.mean_squared_error(labels=q_targets,
                                              predictions=q_predictions)
     optimizer = tf_v1.train.AdamOptimizer(learning_rate=self.lr_ph)
     train_op = get_clipped_train_op(q_loss,
                                     optimizer=optimizer,
                                     var_list=self.q_net.trainable_vars,
                                     clip_norm=self.clip_norm)
     self.q_net.setup_loss(q_loss, train_op)
Exemplo n.º 5
0
    def _update_local_control_variate(self,
                                      control_variate,
                                      idx,
                                      elbo_hmc,
                                      assign=True,
                                      decay=0.9):
        """
        Moving average update of control variate if using a control variate for each point in training set.
        Assumes that for first few (self.control_var_independent_iters) iterations, use global control variate,
        and then remaining iterations use local one. Note that sometimes we want to update the control variate,
        sometimes we don't. This is controlled by the `assign` argument.
        """
        # Find update for relevant elements in control_variate vector
        # and calculate their updated values
        control_variate_local_update = decay * tf.gather(
            control_variate, idx) + (1. - decay) * elbo_hmc

        # Find update if using using global control variate at current iteration
        control_variate_global_update = decay * control_variate[0] + (
            1. - decay) * tf.reduce_mean(elbo_hmc)
        if assign:
            # control_variate is a variable
            control_variate_local = tf.scatter_update(
                control_variate, idx, control_variate_local_update)
        else:
            # control_variate is a tensor
            control_variate_local = tf.tensor_scatter_nd_update(
                control_variate, tf.expand_dims(idx, 1),
                control_variate_local_update)

        # Tile scalar control variate to match shape of local control variate
        control_variate_global = tf.fill(control_variate.get_shape(),
                                         control_variate_global_update)
        new_cv_value = tf.where(
            self.global_step > self.control_var_independent_iters,
            control_variate_local, control_variate_global)
        if assign:
            cv_update = control_variate.assign(new_cv_value)
            return cv_update
        else:
            return new_cv_value
Exemplo n.º 6
0
  def build_graph(parameters):
    """Build the tensor_scatter_update op testing graph."""
    input_tensor = tf.compat.v1.placeholder(
        dtype=parameters["input_dtype"],
        name="input",
        shape=parameters["input_shape"])
    # The indices will be a list of "input_shape".
    indices_tensor = tf.compat.v1.placeholder(
        dtype=tf.int32,
        name="indices",
        shape=([parameters["updates_count"],
                len(parameters["input_shape"])]))
    # The updates will be a list of scalar, shaped of "updates_count".
    updates_tensors = tf.compat.v1.placeholder(
        dtype=parameters["input_dtype"],
        name="updates",
        shape=[parameters["updates_count"]])

    out = tf.tensor_scatter_nd_update(input_tensor, indices_tensor,
                                      updates_tensors)
    return [input_tensor, indices_tensor, updates_tensors], [out]
Exemplo n.º 7
0
    def _grow_alive_seq(self, state):
        """Grow alive sequences by one token, and collect top 2*beam_size sequences.

    2*beam_size sequences are collected because some sequences may have reached
    the EOS token. 2*beam_size ensures that at least beam_size sequences are
    still alive.

    Args:
      state: A dictionary with the current loop state.
    Returns:
      Tuple of
      (Top 2*beam_size sequences [batch_size, 2 * beam_size, cur_index + 1],
       Scores of returned sequences [batch_size, 2 * beam_size],
       New alive cache, for each of the 2 * beam_size sequences)
    """
        i = state[_StateKeys.CUR_INDEX]
        alive_seq = state[_StateKeys.ALIVE_SEQ]
        alive_log_probs = state[_StateKeys.ALIVE_LOG_PROBS]
        alive_cache = state[_StateKeys.ALIVE_CACHE]

        beams_to_keep = 2 * self.beam_size

        # Get logits for the next candidate IDs for the alive sequences. Get the new
        # cache values at the same time.
        if self.padded_decode:
            flat_ids = tf.reshape(
                tf.slice(alive_seq, [0, 0, i],
                         [self.batch_size, self.beam_size, 1]),
                [self.batch_size * self.beam_size, -1])
        else:
            flat_ids = _flatten_beam_dim(alive_seq)  # [batch_size * beam_size]
        flat_cache = tf.nest.map_structure(_flatten_beam_dim, alive_cache)

        flat_logits, flat_cache = self.symbols_to_logits_fn(
            flat_ids, i, flat_cache)

        # Unflatten logits to shape [batch_size, beam_size, vocab_size]
        logits = _unflatten_beam_dim(flat_logits, self.batch_size,
                                     self.beam_size)
        new_cache = tf.nest.map_structure(
            lambda t: _unflatten_beam_dim(t, self.batch_size, self.beam_size),
            flat_cache)

        # Convert logits to normalized log probs
        candidate_log_probs = _log_prob_from_logits(logits)

        # Calculate new log probabilities if each of the alive sequences were
        # extended # by the the candidate IDs.
        # Shape [batch_size, beam_size, vocab_size]
        log_probs = candidate_log_probs + tf.expand_dims(alive_log_probs,
                                                         axis=2)

        # Each batch item has beam_size * vocab_size candidate sequences. For each
        # batch item, get the k candidates with the highest log probabilities.
        flat_log_probs = tf.reshape(log_probs,
                                    [-1, self.beam_size * self.vocab_size])
        topk_log_probs, topk_indices = tf.nn.top_k(flat_log_probs,
                                                   k=beams_to_keep)

        # Extract the alive sequences that generate the highest log probabilities
        # after being extended.
        topk_beam_indices = topk_indices // self.vocab_size
        topk_seq, new_cache = _gather_beams([alive_seq, new_cache],
                                            topk_beam_indices, self.batch_size,
                                            beams_to_keep)

        # Append the most probable IDs to the topk sequences
        topk_ids = topk_indices % self.vocab_size
        if self.padded_decode:
            topk_seq = tf.transpose(topk_seq, perm=[2, 0, 1])
            topk_seq = tf.tensor_scatter_nd_update(topk_seq, [i + 1], topk_ids)
            topk_seq = tf.transpose(topk_seq, perm=[1, 2, 0])
        else:
            topk_ids = tf.expand_dims(topk_ids, axis=2)
            topk_seq = tf.concat([topk_seq, topk_ids], axis=2)
        return topk_seq, topk_log_probs, new_cache
    def __init__(self,
                 sess,
                 model,
                 batch_size=1,
                 confidence=CONFIDENCE,
                 targeted=TARGETED,
                 learning_rate=LEARNING_RATE,
                 binary_search_steps=BINARY_SEARCH_STEPS,
                 max_iterations=MAX_ITERATIONS,
                 abort_early=ABORT_EARLY,
                 initial_const=INITIAL_CONST,
                 boxmin=-0.5,
                 boxmax=0.5,
                 x_window=0,
                 y_window=0,
                 window_size=-1):
        """
        The L_2 optimized attack. 

        This attack is the most efficient and should be used as the primary 
        attack to evaluate potential defenses.

        Returns adversarial examples for the supplied model.

        confidence: Confidence of adversarial examples: higher produces examples
          that are farther away, but more strongly classified as adversarial.
        batch_size: Number of attacks to run simultaneously.
        targeted: True if we should perform a targetted attack, False otherwise.
        learning_rate: The learning rate for the attack algorithm. Smaller values
          produce better results but are slower to converge.
        binary_search_steps: The number of times we perform binary search to
          find the optimal tradeoff-constant between distance and confidence. 
        max_iterations: The maximum number of iterations. Larger values are more
          accurate; setting too small will require a large learning rate and will
          produce poor results.
        abort_early: If true, allows early aborts if gradient descent gets stuck.
        initial_const: The initial tradeoff-constant to use to tune the relative
          importance of distance and confidence. If binary_search_steps is large,
          the initial constant is not important.
        boxmin: Minimum pixel value (default -0.5).
        boxmax: Maximum pixel value (default 0.5).
        """
        if window_size == -1:
            window_size = model.image_size

        image_size, num_channels, num_labels = model.image_size, model.num_channels, model.num_labels
        self.sess = sess
        self.TARGETED = targeted
        self.LEARNING_RATE = learning_rate
        self.MAX_ITERATIONS = max_iterations
        self.BINARY_SEARCH_STEPS = binary_search_steps
        self.ABORT_EARLY = abort_early
        self.CONFIDENCE = confidence
        self.initial_const = initial_const
        self.batch_size = batch_size

        self.repeat = binary_search_steps >= 10

        self.I_KNOW_WHAT_I_AM_DOING_AND_WANT_TO_OVERRIDE_THE_PRESOFTMAX_CHECK = False

        shape = (batch_size, window_size, window_size, num_channels)

        # the variable we're going to optimize over
        modifier = tf.Variable(np.zeros(
            shape, dtype=np.float32))  #qui ridimensionare per fare porzione

        # these are variables to be more efficient in sending data to tf
        self.timg = tf.Variable(np.zeros(shape), dtype=tf.float32)
        self.tlab = tf.Variable(np.zeros((batch_size, num_labels)),
                                dtype=tf.float32)
        self.const = tf.Variable(np.zeros(batch_size), dtype=tf.float32)

        # and here's what we use to assign them
        self.assign_timg = tf.placeholder(tf.float32, shape)
        self.assign_tlab = tf.placeholder(tf.float32, (batch_size, num_labels))
        self.assign_const = tf.placeholder(tf.float32, [batch_size])

        # the resulting image, tanh'd to keep bounded from boxmin to boxmax
        self.boxmul = (boxmax - boxmin) / 2.
        self.boxplus = (boxmin + boxmax) / 2.

        ###################################################################### editing

        mask = tf.zeros((batch_size, image_size, image_size, num_channels),
                        tf.float32)
        # Get input shapes
        modifier_shape = tf.shape(modifier)
        mask_shape = tf.shape(mask)
        # Make indices grid
        oo, ii, jj, kk = tf.meshgrid(tf.range(modifier_shape[0]),
                                     tf.range(modifier_shape[1]),
                                     tf.range(modifier_shape[2]),
                                     tf.range(modifier_shape[3]),
                                     indexing='ij')
        # Shift indices
        ii += y_window
        jj += x_window
        # Scatter update
        mask_to_apply = tf.tensor_scatter_nd_update(
            mask, tf.stack([oo, ii, jj, kk], axis=-1), modifier)

        self.newimg = tf.tanh(mask_to_apply +
                              self.timg) * self.boxmul + self.boxplus

        ###################################################################### editing

        # prediction BEFORE-SOFTMAX of the model
        self.output = model.predict(self.newimg)

        # distance to the input data
        self.l2dist = tf.reduce_sum(
            tf.square(self.newimg -
                      (tf.tanh(self.timg) * self.boxmul + self.boxplus)),
            [1, 2, 3])

        # compute the probability of the label class versus the maximum other
        real = tf.reduce_sum((self.tlab) * self.output, 1)
        other = tf.reduce_max(
            (1 - self.tlab) * self.output - (self.tlab * 10000), 1)

        if self.TARGETED:
            # if targetted, optimize for making the other class most likely
            loss1 = tf.maximum(0.0, other - real + self.CONFIDENCE)
        else:
            # if untargeted, optimize for making this class least likely.
            loss1 = tf.maximum(0.0, real - other + self.CONFIDENCE)

        # sum up the losses
        self.loss2 = tf.reduce_sum(self.l2dist)
        self.loss1 = tf.reduce_sum(self.const * loss1)
        self.loss = self.loss1 + self.loss2

        # Setup the adam optimizer and keep track of variables we're creating
        start_vars = set(x.name for x in tf.global_variables())
        optimizer = tf.train.AdamOptimizer(self.LEARNING_RATE)
        self.train = optimizer.minimize(self.loss, var_list=[modifier])
        end_vars = tf.global_variables()
        new_vars = [x for x in end_vars if x.name not in start_vars]

        # these are the variables to initialize when we run
        self.setup = []
        self.setup.append(self.timg.assign(self.assign_timg))
        self.setup.append(self.tlab.assign(self.assign_tlab))
        self.setup.append(self.const.assign(self.assign_const))

        self.init = tf.variables_initializer(var_list=[mask] + new_vars)