NLP --- >对抗学习:从FGM, PGD到FreeLB

本文介绍了自然语言处理中对抗学习的发展,重点关注了一阶扰动场景。从基础的Fast Gradient Method (FGM)、Projected Gradient Descent (PGD)到更高效的Free Adversarial Training (FreeAT)、You Only Propagate Once (YOPO)以及State-of-the-Art的FreeLB。对抗训练旨在增强模型的鲁棒性和泛化能力,通过在输入中添加扰动来构造对抗样本进行训练。文章详细阐述了各种算法的工作原理及优缺点,并提供了相关算法的PyTorch实现链接。
摘要由CSDN通过智能技术生成

背景

我们知道,对抗学习最初在生成模型中应用,比如最简单的GAN,能够生成以假乱真的图像等;后来该模型被用于判别模型中,因为普通的图像分类器泛化能力差,易受攻击导致分类错误,通过增加对抗训练,能够有效提高模型的鲁棒性,同时也能提高模型的泛化能力。

对抗训练中关键的是需要找到对抗样本,通常是对原始的输入添加一定的扰动来构造,然后放给模型训练,这样模型就有了识别对抗样本的能力。其中的关键技术在于如果构造扰动,使得模型在不同的攻击样本中均能够具备较强的识别性。

本文针对自然语言中的对抗学习,针对攻击的“一阶扰动”场景,总结了最近的工作进展,涉及到的知识包括:基本单步算法FGM,“一阶扰动”最强多步算法PGD,以及针对时耗等改进的FreeAT,YOPO和FreeLB,其中FreeLB成为了目前刷榜的SOA。

基础知识

对抗训练,简单来说,就是在原始输入样本x加上一个扰动 r a d v r_{adv} radv,得到对抗样本后,用其进行训练,2018年Madry在ICLR中[1]针对对抗学习,将此类问题定义为一个Min-Max的公式,即:
m i n θ E ( x , y ) ∼ D [ m a x r a d v ∈ S L ( θ , x + r a d v , y ) ] − − − ( 1 ) \underset {\theta}{min}\mathbb E(x,y)\sim D[\underset{r_{adv\in S}}{max}L(\theta, x+r_{adv}, y)] --- (1) θminE(x,y)D[radvSmaxL(θ,x+radv,y)]1

该公式分为两个部分,一个是内部损失函数的最大化,一个是外部风险的最小化。

  • 内部max,L为定义的损失函数,S为扰动的空间,此时我们的目的是求得让判断失误最多情况下扰动的量,即求得最佳的攻击参数;
  • 外部min,针对上述的攻击,找到最鲁邦的模型参数,也就是防御,进一步优化模型参数,使得在整个数据分布的期望还是最小。

至于公式(1)的定义是否合理,内部通过max优化找到对抗样本是否足够,遇到其他的对抗样本模型是否依然鲁棒?Madry在论文中给了证明,并认为:通过PGD优化找到的对抗样本,将其进行训练使得在这些对抗样本上神经网络的loss很小,那么这个神经网络也就可以抵抗其他的对抗样本,并且说针对内部非凸的优化,PGD能够成功将其解决

FGM

在PGD提出之前,Goodfellow 在17年提出FGM,其增加的扰动为:
r a d v = ϵ ⋅ g / ∣ ∣ g ∣ ∣ 2 g = ▽ x L ( θ , x , y ) r_{adv} = \epsilon \cdot g/||g||_2\\ g = \triangledown_x L(\theta,x,y) radv=ϵg/g2g=xL(θ,x,y)

新增的对抗样本为
x a d v = x + r a d v x_{adv} = x + r_{adv} xadv=x+radv

关键代码实现部分按照【训练技巧】功守道:NLP中的对抗训练 + PyTorch实现

class FGM():
def attack(self, epsilon=1., emb_name='emb.'):
        # emb_name这个参数要换成你模型中embedding的参数名
        for name, param in self.model.named_parameters():
            if param.requires_grad and emb_name in name:
                self.backup[name] = param.data.clone()
                norm = torch.norm(param.grad)
                if norm != 0 and not torch.isnan(norm):
                    r_at = epsilon * param.grad / norm
                    param.data.add_(r_at)
---------------------------------------------

fgm = FGM(model)
for batch_input, batch_label in data:
    # 正常训练
    loss = model(batch_input, batch_label)
    loss.backward() # 反向传播,得到正常的grad
    # 对抗训练
    fgm.attack() # 在embedding上添加对抗扰动
    loss_adv = model(batch_input, batch_label)
    loss_adv.backward() # 反向传播,并在正常的grad基础上,累加对抗训练的梯度
    fgm.restore() # 恢复embedding参数
    optimizer.step()# 梯度下降,更新参数 
    model.zero_grad()

PGD

Project Gradient Descent 是一种迭代攻击,相比于普通的FGM 仅做一次迭代,PGD是做多次迭代,每次走一小步,每次迭代都会将扰动投射到规定范围内。
r a d v t + 1 = Π ∣ ∣ r a d v ∣ ∣ F ≤ ϵ ( r a d v t + α g ( r a d v t ) / ∣ ∣ g ( r a d v t ) ∣ ∣ 2 ) r_{adv}^{t+1} = \Pi_{||r_{adv}||_F\leq \epsilon}(r_{adv}^t + \alpha g(r_{adv}^t)/||g(r_{adv}^t)||_2) radvt+1=ΠradvFϵ(radvt+αg(radvt)/g(radvt)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值