def forward(self, examples, *args, **kwargs): # ARGS should have one element, which serves as the tau value tolerance = 1e-9 scale_factor = 0.9 # To compute Relu(abs(delta_i) - Tau) # first put tau in right shape tau = self.tau.view((-1, ) + (1, ) * (examples.dim() - 1)) tau = tau.expand_as(examples) # Then Relu(abs(delta_i) - Tau) diff = nn.functional.relu(torch.abs(examples - self.fix_im)) # and compute example-wise sums diff = diff.sum(tuple(range(1, diff.dim()))) # And downscale taus by scale factor mask = diff < tolerance tau_updater = torch.ones_like(self.tau) tau_updater[mask] = scale_factor self.tau = self.tau * tau_updater return diff ''' while scale_factor * tau > l_inf_dist: tau *= scale_factor assert tau > l_inf_dist ''' delta_minus_taus = torch.clamp(torch.abs(examples - self.fix_im) - tau, min=0.0) batchwise = utils.batchwise_norm(delta_minus_taus, 'inf', dim=0) return batchwise.squeeze()
def norm(self, lp='inf'): if isinstance(lp, int) or lp == 'inf': return utils.batchwise_norm( self.xform_params - self.identity_params, lp, dim=0, ) else: assert lp == 'smooth' return self.smoothness_norm()
def norm(self, lp='inf'): """ Returns the 'norm' of this transformation in terms of an LP norm on the parameters, summed across each transformation per minibatch ARGS: lp : int or 'inf' - which lp type norm we use """ if isinstance(lp, int) or lp == 'inf': identity_params = Variable(self.identity_params(self.img_shape)) return utils.batchwise_norm(self.xform_params - identity_params, lp, dim=0) else: assert lp == 'stAdv' return self._stAdv_norm()
def forward(self, examples, *args, **kwargs): # ARGS should have one element, which serves as the tau value tau = 8.0 / 255.0 # starts at 1 each time? scale_factor = 0.9 l_inf_dist = float(torch.max(torch.abs(examples - self.fix_im))) ''' while scale_factor * tau > l_inf_dist: tau *= scale_factor assert tau > l_inf_dist ''' delta_minus_taus = torch.clamp(torch.abs(examples - self.fix_im) - tau, min=0.0) batchwise = utils.batchwise_norm(delta_minus_taus, 'inf', dim=0) return batchwise.squeeze()
def forward(self, examples, *args, **kwargs): """ Computes lp loss between identity map and spatial transformation. There better be a kwarg with key 'spatial' which is as FullSpatial object describing how the examples were generated from the originals """ st_obj = kwargs['spatial'] assert isinstance(st_obj, st.FullSpatial) # First create the identity map and make same type as examples identity_map = Variable(st_obj.identity_params(examples.shape)) if examples.is_cuda: identity_map.cuda() # Then take diffs and take lp norms diffs = st_obj.grid_params - identity_map lp_norm = utils.batchwise_norm(diffs, self.lp, dim=0) return lp_norm # return Nx1 variable, will sum in parent class
def perturbation_norm(self, x=None, lp_style=None): lp_style = lp_style or self.lp_style assert isinstance(lp_style, int) or lp_style == 'inf' return utils.batchwise_norm(self.delta, lp=lp_style)
def norm(self, lp='inf'): identity_params = Variable(self.identity_params(self.img_shape)) return utils.batchwise_norm(self.xform_params - identity_params, lp, dim=0)
def forward(self, examples, *args, **kwargs): return utils.batchwise_norm(examples - self.fix_im, 'inf')
def norm(self, lp='inf'): return utils.batchwise_norm(self.xform_params, lp, dim=0)
def attack(self, examples, labels, lp_bound, num_tries=100, verbose=True): """ For a given minibatch of examples, uniformly randomly generates num_tries uniform elements from the lp ball of size lp_bound. The minimum distance incorrectly classified object is kept, otherwise the original is returned ARGS: examples: Nxcxwxh tensor for N examples. NOT NORMALIZED (i.e. all vals are between 0.0 and 1.0 ) labels: single-dimension tensor with labels of examples (in same order) lp_bound: float - how far we're allowed to guess in lp-distance num_tries : how many random perturbations we try per example RETURNS: {'min_dist': ..., 'adv_ex': tensor output} """ # NOTE: THIS IS SUPER NAIVE AND WE CAN DO UNIFORM RANDOM WAAAAY BETTER num_examples = examples.shape[0] dim = examples.dim() expand_to_dim = lambda t: t.view(num_examples, *([1] * dim)) var_examples = Variable(examples) # no grads needed var_labels = Variable(labels) if self.lp_norm == 'linf': random_guesser = self._random_linf_perturbation lp_type = 'inf' else: lp_type = int(self.lp_norm[1:]) raise NotImplementedError lp_vec = torch.ones(num_examples).type(self._dtype) * lp_bound outputs = {'best_dist': torch.ones(num_examples).type(self._dtype) *\ MAXFLOAT, 'best_adv_images': examples.clone(), 'original_images': examples.clone()} ###################################################################### # Loop through each try # ###################################################################### for try_no in xrange(num_tries): if verbose and try_no % (num_tries / 10) == 0 and try_no > 1: print "Completed %03d random guesses..." % try_no # get random perturbation random_guess = var_examples + random_guesser(var_examples, lp_vec) random_guess = utils.clip_0_1(random_guess) loss = self.loss_fxn.forward(random_guess, var_labels, return_type='vector') loss = loss.type(self._dtype) converse_loss = 1 - loss # get distances per example batchwise_norms = utils.batchwise_norm(random_guess - var_examples, lp_type, dim=0) # Reflect this iteration in outputs and lp_tensor # build incorrect index vector # comp_1[i] = batchwise_norm[i] if i is adversarial, MAXFLOAT o.w. comp_1 = (loss * batchwise_norms + converse_loss * (MAXFLOAT)).data # figure out which random guesses to keep to_keep = (comp_1 < outputs['best_dist']).type(self._dtype) to_keep = expand_to_dim(to_keep) to_keep_converse = 1 - to_keep # compute new best_dists and best_adv_images new_bests = (random_guess.data * to_keep + outputs['best_adv_images'] * to_keep_converse) new_best_dists = torch.min(comp_1, outputs['best_dist']) outputs['best_dist'] = new_best_dists outputs['best_adv_images'] = new_bests if verbose: num_successful = len( [_ for _ in outputs['best_dist'] if _ < MAXFLOAT]) print "\n Ending attack" print "Successful attacks for %03d/%03d examples in CONTINUOUS" %\ (num_successful, num_examples) return outputs