def __init__(self, sess, model, batch_size, confidence, targeted, learning_rate, perturb_window, binary_search_steps, max_iterations, dis_metric, ensemble_size, ground_truth, abort_early, initial_const, clip_min, clip_max, dist_tolerance, num_labels, shape): """ 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 model: a cleverhans.model.Model object. :param batch_size: Number of attacks to run simultaneously. :param confidence: Confidence of adversarial examples: higher produces examples with larger l2 distortion, but more strongly classified as adversarial. :param targeted: boolean controlling the behavior of the adversarial examples produced. If set to False, they will be misclassified in any wrong class. If set to True, they will be misclassified in a chosen target class. :param learning_rate: The learning rate for the attack algorithm. Smaller values produce better results but are slower to converge. :param binary_search_steps: 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: 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: If true, allows early aborts if gradient descent is unable to make progress (i.e., gets stuck in a local minimum). :param initial_const: The initial tradeoff-constant to use to tune the relative importance of size of the pururbation 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 clip_min: (optional float) Minimum input component value. :param clip_max: (optional float) Maximum input component value. :param num_labels: the number of classes in the model's output. :param shape: the shape of the model's input tensor. :param dis_metric: the distance metirc, 1 for l2, 2 for soft-dtw """ self.sess = sess self.TARGETED = targeted self.LEARNING_RATE = learning_rate self.perturb_window = perturb_window self.MAX_ITERATIONS = max_iterations self.dis_metric = dis_metric self.ensemble_size = ensemble_size 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.dist_tolerance = dist_tolerance self.clip_min = clip_min self.clip_max = clip_max self.model = model self.perturb_window = perturb_window self.repeat = binary_search_steps >= 10 self.ground_truth = ground_truth self.shape = shape = tuple([batch_size] + list(shape)) shape_perturb = tuple([batch_size, perturb_window, 1]) # self.transform_shape = transform_shape = tuple([transform_batch_size] + list(transform_shape)) # self.shape = shape = tuple(list(shape)) # the variable we're going to optimize over modifier = tf.Variable(np.zeros(shape_perturb, dtype=np_dtype)) tile_times = math.ceil(data_len / perturb_window) tile_times_lb = max(math.floor(tile_times / 3), 1) # these are variables to be more efficient in sending data to tf self.timg = tf.Variable(np.zeros(shape), dtype=tf_dtype, name='timg') self.tlab = tf.Variable(np.zeros((batch_size, num_labels)), dtype=tf_dtype, name='tlab') self.const = tf.Variable(np.zeros(batch_size), dtype=tf_dtype, name='const') # and here's what we use to assign them self.assign_timg = tf.placeholder(tf_dtype, shape, name='assign_timg') self.assign_tlab = tf.placeholder(tf_dtype, (batch_size, num_labels), name='assign_tlab') self.assign_const = tf.placeholder(tf_dtype, [batch_size], name='assign_const') # the resulting instance, tanh'd to keep bounded from clip_min # to clip_max # self.newimg = (tf.tanh(modifier + self.timg) + 1) / 2 # self.newimg = self.newimg * (clip_max - clip_min) + clip_min #self.modifier_tile = tf.tile(modifier, ) d = tf.expand_dims(tf.constant([0, 0]), axis=0) rand_tile_times = tf.random_shuffle( tf.range(tile_times_lb, tile_times + 1)) tile_range = math.floor(tile_times / 2) + 1 ensemblesize = math.ceil(200 / tile_range) for l in range(tile_range): rand_times = tf.expand_dims(rand_tile_times[l], axis=0) rand_times = tf.concat([tf.constant([1]), rand_times], axis=0) rand_times = tf.concat([rand_times, tf.constant([1])], axis=0) modifier_tile = tf.tile(modifier, rand_times) modifier_shape = tf.shape(modifier_tile)[1] b = tf.expand_dims(modifier_shape, axis=0) c = tf.concat([tf.constant([0]), data_len - b], axis=0) c = tf.expand_dims(c, axis=0) c = tf.concat([d, c], axis=0) c = tf.concat([c, d], axis=0) start_p = tf.cond(tf.equal(modifier_shape, tf.constant(data_len)), lambda: tf.constant(0), lambda: modifier_shape) modifier_tile = tf.reshape(tf.pad(modifier_tile, c, "CONSTANT"), [1, data_len, 1]) self.newimg = tf.slice(modifier_tile, (0, 0, 0), shape) + self.timg if l == 0: batch_newdata = EOT_time(modifier_tile, start_p, ensemblesize) + self.timg else: batch_newdata = tf.concat([ batch_newdata, EOT_time(modifier_tile, start_p, ensemblesize) + self.timg ], axis=0) self.batch_newimg = zero_mean(batch_newdata) self.loss_batch = model.get_logits(self.batch_newimg) self.batch_tlab = tf.tile(self.tlab, (self.batch_newimg.shape[0], 1)) self.xent = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.loss_batch, labels=self.batch_tlab)) #self.xent_rest = tf.reduce_mean( # tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.loss_batch_rest, labels=self.batch_tlab_rest)) self.outputxent = tf.expand_dims(self.xent, 0) self.output = tf.expand_dims(tf.reduce_mean(self.loss_batch, axis=0), 0) # distance to the input data # self.other = (tf.tanh(self.timg) + 1) / \ # 2 * (clip_max - clip_min) + clip_min # self.l2dist = reduce_sum(tf.square(self.newimg - self.other), # list(range(1, len(shape)))) if self.dis_metric == 1: self.dist = tf.reduce_sum(tf.square(modifier_tile), list(range(1, len(shape)))) else: if self.dis_metric == 2: self.dist = tf.reduce_sum( mysoftdtw(self.timg, modifier_tile, 1) / 9000) else: _, distvar = tf.nn.moments(tf.multiply( tf.concat([modifier_tile, [[[0.]]]], 1) - tf.concat([[[[0.]]], modifier_tile], 1), Seq1()), axes=[1]) self.dist = 10000 * distvar #self.l2dist= tf.reduce_sum(mysoftdtw(self.timg, modifier, 1)) # self.sdtw = reduce_sum(mysquare_new(self.timg, modifier, 1),list(range(1, len(shape)))) # 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 targeted, optimize for making the other class most likely #loss1 = tf.maximum(ZERO(), other - real + self.CONFIDENCE) #else: # if untargeted, optimize for making this class least likely. #loss1 = tf.maximum(ZERO(), real - other + self.CONFIDENCE) # sum up the losses self.loss2 = tf.reduce_sum(self.dist) # self.loss2 = tf.reduce_sum(self.sdtw) #self.loss1 = tf.reduce_sum(self.const * (self.xent+self.xent_rest)) self.loss1 = tf.reduce_sum(self.const * self.xent) 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]) # tf.summary.scalar('loss', self.loss) # self.train_writer = tf.summary.FileWriter('./log', self.sess.graph) # self.merge = tf.summary.merge_all() 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=[modifier] + new_vars)
def gradient_descent(self, sess, model): def compare(x, y): if self.TARGETED: return x == y else: return x != y shape = self.shape # self.shape = shape = tuple(list(shape)) # the variable we're going to optimize over modifier = tf.Variable(np.zeros(shape, dtype=np_dtype), name='modifier') # these are variables to be more efficient in sending data to tf canchange = tf.Variable(np.zeros(shape), dtype=np_dtype, name='canchange') simg = tf.Variable(np.zeros(shape), dtype=np_dtype, name='simg') original = tf.Variable(np.zeros(shape), dtype=np_dtype, name='original') timg = tf.Variable(np.zeros(shape), dtype=np_dtype, name='timg') tlab = tf.Variable(np.zeros((self.batch_size, self.num_labels)), dtype=np_dtype, name='tlab') const = tf.placeholder(tf.float32, [], name='const') # and here's what we use to assign them assign_modifier = tf.placeholder(np_dtype, shape, name='assign_modifier') assign_canchange = tf.placeholder(np_dtype, shape, name='assign_canchange') assign_simg = tf.placeholder(np_dtype, shape, name='assign_simg') assign_original = tf.placeholder(np_dtype, shape, name='assign_original') assign_timg = tf.placeholder(np_dtype, shape, name='assign_timg') assign_tlab = tf.placeholder(np_dtype, (self.batch_size, self.num_labels), name='assign_tlab') # these are the variables to initialize when we run set_modifier = tf.assign(modifier, assign_modifier) setup = [] setup.append(tf.assign(canchange, assign_canchange)) setup.append(tf.assign(timg, assign_timg)) setup.append(tf.assign(original, assign_original)) setup.append(tf.assign(simg, assign_simg)) setup.append(tf.assign(tlab, assign_tlab)) # the resulting instance, tanh'd to keep bounded from clip_min to clip_max # self.newimg = (tf.tanh(modifier + self.timg) + 1) / 2 # self.newimg = self.newimg * (clip_max - clip_min) + clip_min newimg = (modifier + simg) * canchange + (1 - canchange) * original # prediction BEFORE-SOFTMAX of the model output = model.get_logits(newimg) # distance to the input data # self.other = (tf.tanh(self.timg) + 1) / \ # 2 * (clip_max - clip_min) + clip_min # self.l2dist = reduce_sum(tf.square(self.newimg - self.other), # list(range(1, len(shape)))) # l2dist = tf.reduce_sum(tf.square(newimg - timg), list(range(1, len(shape)))) l2dist = mysoftdtw(simg, modifier, 0.1) # l2dist = reduce_sum(mysquare_new(self.timg, modifier, 1),list(range(1, len(shape)))) # compute the probability of the label class versus the maximum other real = tf.reduce_sum((tlab) * output, 1) other = tf.reduce_max((1 - tlab) * output - tlab * 10000, 1) if self.TARGETED: # if targeted, optimize for making the other class most likely loss1 = tf.maximum(ZERO(), other - real + self.CONFIDENCE) else: # if untargeted, optimize for making this class least likely. loss1 = tf.maximum(ZERO(), real - other + self.CONFIDENCE) # sum up the losses loss2 = tf.reduce_sum(l2dist) loss = const * loss1 + loss2 outgrad = tf.gradients(loss, [modifier])[0] # 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) train = optimizer.minimize(loss, var_list=[modifier]) end_vars = tf.global_variables() new_vars = [x for x in end_vars if x.name not in start_vars] init = tf.variables_initializer( var_list=[modifier, canchange, simg, original, timg, tlab] + new_vars) def doit(oimgs, labs, starts, valid, CONST): imgs = np.array(oimgs) starts = np.array(starts) sess.run(init) sess.run( setup, { assign_timg: imgs, assign_tlab: labs, assign_simg: starts, assign_original: oimgs, assign_canchange: valid }) while CONST < self.LARGEST_CONST: print('try const', CONST) prev = 1e6 for step in range(self.MAX_ITERATIONS): feed_dict = {const: CONST} #remember the old value oldmodifier = self.sess.run(modifier) if step % (self.MAX_ITERATIONS // 100) == 0: print(step, *sess.run((loss1, loss2), feed_dict=feed_dict)) #perform the update step _, l, works, scores = sess.run( [train, loss, loss1, output], feed_dict=feed_dict) if self.ABORT_EARLY and step % ( (self.MAX_ITERATIONS // 100) or 1) == 0: if l > prev * .9999: break prev = l if works < 0.0001 and self.ABORT_EARLY: print('loss:', works) self.sess.run(set_modifier, {assign_modifier: oldmodifier}) grads, scores, nimg = sess.run( (outgrad, output, newimg), feed_dict=feed_dict) # l2s = np.square(nimg-imgs).sum(axis=(1,2,3)) return grads, scores, nimg, CONST CONST *= self.const_factor return doit
a = np.zeros(5) b = np.array([-1, 1, -1, 1, -1], dtype=np.float64) l2_ab = np.sum(np.square(b-a)) c = np.array([-np.sqrt(0.5)*2, -np.sqrt(0.5), 0, np.sqrt(0.5), np.sqrt(0.5)*2], dtype=np.float64) l2_ac = np.sum(np.square(c-a)) from mysoftdtw_c_wd import mysoftdtw import tensorflow as tf tmp_a = a.reshape((1, 5, 1)) tmp_a = np.float32(tmp_a) tmp_b = b.reshape((1, 5, 1)) tmp_b = np.float32(tmp_b) tmp_c = c.reshape((1, 5, 1)) tmp_c = np.float32(tmp_c) A = tf.constant(tmp_a) B = tf.constant(tmp_b) C = tf.constant(tmp_c) gamma = tf.constant(0.1, dtype=tf.float32) Z_ab = mysoftdtw(A, B, gamma) Z_ac = mysoftdtw(A, C, gamma) sess = tf.Session() tf.global_variables_initializer().run(session=sess) print(Z_ab.eval(session=sess)) print(Z_ac.eval(session=sess)) diff_ab = np.var(np.diff(c-a)) diff_ac = np.var(np.diff(b-a)) plt.plot(a) plt.plot(b)
def __init__(self, sess, model, batch_size, confidence, targeted, learning_rate, binary_search_steps, max_iterations, abort_early, initial_const, clip_min, clip_max, num_labels, shape): """ 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 model: a cleverhans.model.Model object. :param batch_size: Number of attacks to run simultaneously. :param confidence: Confidence of adversarial examples: higher produces examples with larger l2 distortion, but more strongly classified as adversarial. :param targeted: boolean controlling the behavior of the adversarial examples produced. If set to False, they will be misclassified in any wrong class. If set to True, they will be misclassified in a chosen target class. :param learning_rate: The learning rate for the attack algorithm. Smaller values produce better results but are slower to converge. :param binary_search_steps: 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: 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: If true, allows early aborts if gradient descent is unable to make progress (i.e., gets stuck in a local minimum). :param initial_const: The initial tradeoff-constant to use to tune the relative importance of size of the pururbation 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 clip_min: (optional float) Minimum input component value. :param clip_max: (optional float) Maximum input component value. :param num_labels: the number of classes in the model's output. :param shape: the shape of the model's input tensor. """ 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.clip_min = clip_min self.clip_max = clip_max self.model = model self.repeat = binary_search_steps >= 10 self.shape = shape = tuple([batch_size] + list(shape)) # self.shape = shape = tuple(list(shape)) # the variable we're going to optimize over modifier = tf.Variable(np.zeros(shape, dtype=np_dtype)) # these are variables to be more efficient in sending data to tf self.timg = tf.Variable(np.zeros(shape), dtype=tf_dtype, name='timg') self.tlab = tf.Variable(np.zeros((batch_size, num_labels)), dtype=tf_dtype, name='tlab') self.const = tf.Variable(np.zeros(batch_size), dtype=tf_dtype, name='const') # and here's what we use to assign them self.assign_timg = tf.placeholder(tf_dtype, shape, name='assign_timg') self.assign_tlab = tf.placeholder(tf_dtype, (batch_size, num_labels), name='assign_tlab') self.assign_const = tf.placeholder(tf_dtype, [batch_size], name='assign_const') # the resulting instance, tanh'd to keep bounded from clip_min # to clip_max # self.newimg = (tf.tanh(modifier + self.timg) + 1) / 2 # self.newimg = self.newimg * (clip_max - clip_min) + clip_min self.newimg = modifier + self.timg data_mean, data_var = tf.nn.moments(self.newimg, axes=1) self.newimg = (self.newimg - data_mean) / tf.sqrt(data_var) # distance to the input data # self.other = (tf.tanh(self.timg) + 1) / \ # 2 * (clip_max - clip_min) + clip_min # self.l2dist = reduce_sum(tf.square(self.newimg - self.other), # list(range(1, len(shape)))) # self.l2dist1 = tf.reduce_sum(tf.square(self.newimg - self.timg),list(range(1, len(shape)))) self.l2dist = mysoftdtw(self.timg, modifier, 0.0001) # _, self.l2dist = tf.nn.moments(tf.multiply(tf.concat([modifier, [[[0.]]]], 1) - # tf.concat([[[[0.]]], modifier], 1), Seq1()), axes=[1]) # self.sdtw = reduce_sum(mysquare_new(self.timg, modifier, 1),list(range(1, len(shape)))) # data_mean, data_var = tf.nn.moments(self.newimg, axes=1) # self.newimg = (self.newimg - data_mean)/tf.sqrt(data_var) # self.newimg = tf.stop_gradient(self.newimg) # prediction BEFORE-SOFTMAX of the model self.output = model.get_logits(self.newimg) # 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 targeted, optimize for making the other class most likely loss1 = tf.maximum(ZERO(), other - real + self.CONFIDENCE) else: # if untargeted, optimize for making this class least likely. loss1 = tf.maximum(ZERO(), real - other + self.CONFIDENCE) # loss1 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.output,labels=self.tlab)) # sum up the losses # self.loss3 = tf.reduce_sum(20000*self.loss3) # self.loss2 = tf.reduce_sum(self.l2dist*10000) # self.loss2 = tf.reduce_sum(self.l2dist1) 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]) # tf.summary.scalar('loss', self.loss) # self.train_writer = tf.summary.FileWriter('./log', self.sess.graph) # self.merge = tf.summary.merge_all() 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=[modifier] + new_vars)