基于梯度的攻击——MIM
Posted shona
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于梯度的攻击——MIM相关的知识,希望对你有一定的参考价值。
MIM攻击原论文地址——https://arxiv.org/pdf/1710.06081.pdf
1.MIM攻击的原理
MIM攻击全称是 Momentum Iterative Method,其实这也是一种类似于PGD的基于梯度的迭代攻击算法。它的本质就是,在进行迭代的时候,每一轮的扰动不仅与当前的梯度方向有关,还与之前算出来的梯度方向相关。其中的衰减因子就是用来调节相关度的,decay_factor在(0,1)之间,decay_factor越小,那么迭代轮数靠前算出来的梯度对当前的梯度方向影响越小。其实仔细想想,这样做也很有道理,由于之前的梯度对后面的迭代也有影响,那么这使得,迭代的方向不会跑偏,使得总体的大方向是对的。到目前为止都是笔者对MIM比较感性的认识,下面贴出论文中比较学术的观点。
其实为了加速梯度下降,通过累积损失函数的梯度方向上的矢量,从而(1)稳定更新(2)有助于通过 narrow valleys, small humps and poor local minima or maxima.(专业名词不知道怎么翻译,可以脑补函数图像,大致意思就是,可以有效避免局部最优)
是decay_factor,另外,在原论文中,每一次迭代对x的导数是直接算的1-范数,然后求平均,但在各个算法库以及论文实现的补充中,并没有求平均,估计这个对结果影响不太大。
2.代码实现
class MomentumIterativeAttack(Attack, LabelMixin): """ The L-inf projected gradient descent attack (Dong et al. 2017). The attack performs nb_iter steps of size eps_iter, while always staying within eps from the initial point. The optimization is performed with momentum. Paper: https://arxiv.org/pdf/1710.06081.pdf """ def __init__( self, predict, loss_fn=None, eps=0.3, nb_iter=40, decay_factor=1., eps_iter=0.01, clip_min=0., clip_max=1., targeted=False): """ Create an instance of the MomentumIterativeAttack. :param predict: forward pass function. :param loss_fn: loss function. :param eps: maximum distortion. :param nb_iter: number of iterations :param decay_factor: momentum decay factor. :param eps_iter: attack step size. :param clip_min: mininum value per input dimension. :param clip_max: maximum value per input dimension. :param targeted: if the attack is targeted. """ super(MomentumIterativeAttack, self).__init__( predict, loss_fn, clip_min, clip_max) self.eps = eps self.nb_iter = nb_iter self.decay_factor = decay_factor self.eps_iter = eps_iter self.targeted = targeted if self.loss_fn is None: self.loss_fn = nn.CrossEntropyLoss(reduction="sum") def perturb(self, x, y=None): """ Given examples (x, y), returns their adversarial counterparts with an attack length of eps. :param x: input tensor. :param y: label tensor. - if None and self.targeted=False, compute y as predicted labels. - if self.targeted=True, then y must be the targeted labels. :return: tensor containing perturbed inputs. """ x, y = self._verify_and_process_inputs(x, y) delta = torch.zeros_like(x) g = torch.zeros_like(x) delta = nn.Parameter(delta) for i in range(self.nb_iter): if delta.grad is not None: delta.grad.detach_() delta.grad.zero_() imgadv = x + delta outputs = self.predict(imgadv) loss = self.loss_fn(outputs, y) if self.targeted: loss = -loss loss.backward() g = self.decay_factor * g + normalize_by_pnorm( delta.grad.data, p=1) # according to the paper it should be .sum(), but in their # implementations (both cleverhans and the link from the paper) # it is .mean(), but actually it shouldn‘t matter delta.data += self.eps_iter * torch.sign(g) # delta.data += self.eps / self.nb_iter * torch.sign(g) delta.data = clamp( delta.data, min=-self.eps, max=self.eps) delta.data = clamp( x + delta.data, min=self.clip_min, max=self.clip_max) - x rval = x + delta.data return rval
个人觉得,advertorch中在迭代过程中,应该是对imgadv求导,而不是对delta求导,笔者查看了foolbox和cleverhans的实现,都是对每一轮的对抗样本求导,大家自己实现的时候可以改一下。
以上是关于基于梯度的攻击——MIM的主要内容,如果未能解决你的问题,请参考以下文章