文章目录

  • 背景
    • 基础知识
  • FGM
  • PGD
  • Free adversarial train
    • FreeAT
    • YOPO
    • FreeLB

背景

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

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

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

基础知识

对抗训练,简单来说,就是在原始输入样本x加上一个扰动 radvr_{adv}radv,得到对抗样本后,用其进行训练,2018年Madry在ICLR中[1]针对对抗学习,将此类问题定义为一个Min-Max的公式,即:
minθE(x,y)∼D[maxradv∈SL(θ,x+radv,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,其增加的扰动为:
radv=ϵ⋅g/∣∣g∣∣2g=▽xL(θ,x,y)r_{adv} = \epsilon \cdot g/||g||_2\\ g = \triangledown_x L(\theta,x,y)radv=ϵg/g2g=xL(θ,x,y)

新增的对抗样本为
xadv=x+radvx_{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 / normparam.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是做多次迭代,每次走一小步,每次迭代都会将扰动投射到规定范围内。
radvt+1=Π∣∣radv∣∣F≤ϵ(radvt+αg(radvt)/∣∣g(radvt)∣∣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)2)

g(radvt)=▽radvL(fθ(X+radvt),y)g(r_{adv}^t) = \triangledown_{r_{adv}} L(f_{\theta}(X + r_{adv}^t), y)g(radvt)=radvL(fθ(X+radvt),y)

其中S=r∈RdS = r \in \mathbb R^dS=rRd, ∣∣r∣∣2≤ϵ为扰动的约束空间,α为小步的步长||r||_2 \leq \epsilon为扰动的约束空间,\alpha为小步的步长r2ϵα,这里Πx+S\Pi_{x+S}Πx+S含义时在ϵ\epsilonϵ-ball上执行投射。

在论文中,作者将通过一阶梯度得到的样本称为“一阶对抗”,而在所有的一阶对抗样本中,效果上认为PGD为最优的方法。

  • Πx+S\Pi_{x+S}Πx+S为在ϵ\epsilonϵ-ball球上的投影,即如果我们的扰动幅度过大,我们将origin部分其拉回边界球project处,
  • 多次操作后,即是扰动在球内多次叠加即:
class PGD():def attack(self, epsilon=1., alpha=0.3, emb_name='emb.', is_first_attack=False):# emb_name这个参数要换成你模型中embedding的参数名for name, param in self.model.named_parameters():if param.requires_grad and emb_name in name:if is_first_attack:self.emb_backup[name] = param.data.clone()norm = torch.norm(param.grad)if norm != 0 and not torch.isnan(norm):r_at = alpha * param.grad / normparam.data.add_(r_at)param.data = self.project(name, param.data, epsilon)def project(self, param_name, param_data, epsilon):r = param_data - self.emb_backup[param_name]if torch.norm(r) > epsilon:r = epsilon * r / torch.norm(r)return self.emb_backup[param_name] + r# ----------------pgd = PGD(model)
K = 3
for batch_input, batch_label in data:# 正常训练loss = model(batch_input, batch_label)loss.backward() # 反向传播,得到正常的gradpgd.backup_grad()# 对抗训练for t in range(K):pgd.attack(is_first_attack=(t==0)) #在embedding上添加对抗扰动, first attack时备份param.dataif t != K-1:model.zero_grad()else:pgd.restore_grad()loss_adv = model(batch_input, batch_label)loss_adv.backward() # 反向传播,并在正常的grad基础上,累加对抗训练的梯度pgd.restore() # 恢复embedding参数optimizer.step()# 梯度下降,更新参数model.zero_grad()

Free adversarial train

关于普通的PGD方法,一个epoch的一个batch计算时:

  • 在内层,我们在内层通常经过K次前向后向传播算法,得到k个关于输入的梯度▽x\triangledown_xx
  • 在外层,需要一次前后后向传播算法,得到一个关于神经网络参数θ\thetaθ的梯度▽θ\triangledown_{\theta}θ,然后据此更新神经网络。

相对于普通一个batch的训练,这种方法将计算成本增加K倍,极大影响了效率。其实我们在针对xxxθ\thetaθ计算其中一个梯度时,能几乎无成本地得到另一个的梯度。据此,我们能同时利用更多信息,加快训练,做法有FreeAT、YOPO和FreeLB。

FreeAT

当我们在内层时得到关于模型参数θ\thetaθ和输入xxx的梯度后,连续 K次在同样的batch下训练为了使得训练迭代次数保存不变,我们将总的epochoriginepoch_{origin}epochorigin缩小K倍,即总次数变为epochsorigin/kepochs_{origin}/kepochsorigin/k。也就是说,相比于PGD:

  • 内层外层合并,我们一起计算得到θ\thetaθxxx的梯度,每一步都会更新模型参数和累加扰动;

FreeAT算法流程

输入:训练样本X,扰动边界ϵ\epsilonϵ,学习速率τ\tauτ, 内部步数K
初始化 θ\thetaθ
δ←0\delta \leftarrow 0δ0
for epoch =1… Nep/mN_{ep}/mNep/m do
   for miniBatch B⊂XB\subset XBX do
      for i = 1…m do
         Update θ\thetaθ with sgd
              gθ←E(x,y)∈B[▽θl(x+δ,y,θ)]g_{\theta}\leftarrow \mathbb E_{(x,y)\in B}[\triangledown_{\theta}l(x+\delta, y,\theta)]gθE(x,y)B[θl(x+δ,y,θ)]
              gadv←▽xl(x+δ,y,θ)g_{adv}\leftarrow \triangledown_x l(x+\delta, y,\theta)gadvxl(x+δ,y,θ)
              θ←θ−τgθ\theta \leftarrow \theta-\tau g_{\theta}θθτgθ # 更新模型参数
         Use gradients calculated for the minimization step to update δ\deltaδ
              δ←δ+ϵ⋅sign(gadv)\delta \leftarrow \delta + \epsilon\cdot sign(g_{adv})δδ+ϵsign(gadv) # 累加更新扰动
              δ←clip(δ,−ϵ,ϵ)\delta \leftarrow clip(\delta, -\epsilon, \epsilon)δclip(δ,ϵ,ϵ) # 投射扰动到固定范围
      end for
   end for
end for

另外,可以看出,当下一个minibatch过来的时候,仍然使用上一个minibatch的扰动,即热更新

YOPO

YOPO-m-n算法:

YOPO-m-n尽管仅仅是m次前向后向传播,但是相对于其利用数据m∗nm*nmn次,并且其能够灵活地增加n并且减少m来通过更少的计算消耗获取同样的效果。经验上,如果要获取与PGD-K同样的效果,YOPO需要m∗nalitterlargerm*n \;a \;litter\; largermnalitterlarger的设置。
另外,YOPO-m-n会充分利用每一个前向后向传播结果,m步结果都会被用于更新模型参数。

  • 与YOPO相比,FreeAT-m相比于YOPO-m-1算法,除了YOPO-m-1在更新权重的时候,是在整个min-batch被K次处理后,为了使用动量而完成一次权重更新,而FreeAT是在K次中都要进行权重更新。

YOPO算法流程

Initialize δi1,0{\delta_i^{1,0}}δi1,0
for each input xix_ixi.
For j=1,2,…,m
   Calculate the slack variable p
      p=▽gθ~(l(gθ~(f0(xi+δij,0),θ0)),yi)⋅▽f0(gθ~(f0(xi+δij,0,θ0)))p=\triangledown_{g_{\tilde \theta}}(l(g_{\tilde \theta}(f_0(x_i+\delta^{j,0}_i),\theta_0)), y_i)\cdot \triangledown_{f_0}(g_{\tilde \theta}(f_0(x_i+\delta_i^{j,0},\theta_0)))p=gθ~(l(gθ~(f0(xi+δij,0),θ0)),yi)f0(gθ~(f0(xi+δij,0,θ0))) # 由此可更方便计算出关于δ\deltaδ的梯度, f0f_0f0代表网络结构的第一层
   Update the adversary
   for s=0,1,…,n-1 for fixed p:
      δij,s+1=δij,s+α1p⋅▽δif0(xi+δij,s,θ0),i=1,...,B\delta_i^{j,s+1}=\delta_i^{j,s} + \alpha_1 p\cdot \triangledown_{\delta_i}f_0(x_i+\delta^{j,s}_i,\theta_0), i=1,...,Bδij,s+1=δij,s+α1pδif0(xi+δij,s,θ0),i=1,...,B
   Let δij+1,0=δij,n\delta_i^{j+1,0}=\delta_i^{j,n}δij+1,0=δij,n
Calculate the weight update
   U=∑j=1m▽θ(∑i=1Bl(gθ~(f0(xi+δij,n,θ0)),yi))U= \sum\limits_{j=1}^m\triangledown_{\theta}(\sum\limits_{i=1}^Bl(g_{\tilde \theta}(f_0(x_i+\delta_i^{j,n},\theta_0)), y_i))U=j=1mθ(i=1Bl(gθ~(f0(xi+δij,n,θ0)),yi))
and update the weight θ←θ−α2U\theta \leftarrow \theta-\alpha_2 Uθθα2U

FreeLB

FreeLB综合了FreeAT和YOPO-m-n的思想,其主要不同在于

  • 相比于FreeAT,其在内部max过程的K步中,其不是都更新模型参数θ\thetaθ,而是将K步中的梯度平均,以平均值来更新参数。
  • 相比于YOPO-m-n,其也是将K步(这里指m)中的梯度综合后再更新参数,不同的是其没有更进一步的n层,即使有,也是n个完全相同的值。

FreeLB算法流程

Input: Training samples X={(Z, y)}, perturbation bound ϵ\epsilonϵ, learning rate τ\tauτ, ascend steps K, ascend step size α\alphaα
Initialize θ\thetaθ
for epoch =1…N_{ep} do
   for minibatch B⊂XB\subset XBX do
      δ0←1(Nθ)U(−ϵ,ϵ)\delta_0\leftarrow \frac{1}{\sqrt{(N_{\theta})}} U(-\epsilon, \epsilon)δ0(Nθ)

1U(ϵ,ϵ)
      g0←0g_0\leftarrow 0g00
      for t=1…K do
            Accumulate gradient of parameters θ\thetaθ
                  gt←gt−1+1KEZ,y∈B[▽θL(fθ(X+δt−1),y)]g_t \leftarrow g_{t-1} + \frac{1}{K}\mathbb E_{{Z,y}\in B}[\triangledown_{\theta}L(f_{\theta}(X+\delta_{t-1}),y)]gtgt1+K1EZ,yB[θL(fθ(X+δt1),y)]
            Update the perturbation δ\deltaδ via gradient ascend
                  gadv←▽δL(fθ(X+δt−1),y)g_{adv}\leftarrow \triangledown_{\delta}L(f_{\theta}(X+\delta_{t-1}),y)gadvδL(fθ(X+δt1),y)
                  δt←Π∣∣δ∣∣F≤ϵ(δt−1+α⋅gadv/∣∣gadv∣∣F)\delta_t \leftarrow \Pi_{||\delta||_F\leq \epsilon}(\delta_{t-1}+\alpha\cdot g_{adv}/||g_{adv}||_F)δtΠδFϵ(δt1+αgadv/gadvF)
      end for
      θ←θ−τgK\theta \leftarrow \theta-\tau g_KθθτgK
   end for
end for

欢迎关注公众号:

Ref:

  1. Zhang, D., Zhang, T., Lu, Y., Zhu, Z. & Dong, B. You Only Propagate Once: Accelerating Adversarial Training via Maximal Principle. 17.
  2. Madry, A., Makelov, A., Schmidt, L., Tsipras, D. & Vladu, A. Towards Deep Learning Models Resistant to Adversarial Attacks. arXiv:1706.06083 [cs, stat] (2019).
  3. Zhu, C. et al. FreeLB: Enhanced Adversarial Training for Language Understanding. arXiv:1909.11764 [cs] (2019).
  4. Shafahi, A. et al. Adversarial Training for Free! arXiv:1904.12843 [cs, stat] (2019).
  5. https://blog.csdn.net/jmh1996/article/details/102048395

NLP --- 对抗学习:从FGM, PGD到FreeLB相关推荐

  1. [nlp] 对抗学习 FGM, PGD到FreeLB

    对抗学习总结:FGSM->FGM->PGD->FreeAT, YOPO ->FreeLb->SMART->LookAhead->VAT_zhurui_xiao ...

  2. 【综述】NLP 对抗训练(FGM、PGD、FreeAT、YOPO、FreeLB、SMART)

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

  3. 对抗训练的理解,以及FGM、PGD和FreeLB的详细介绍

    对抗训练基本思想--Min-Max公式 如图所示. 中括号里的含义为,我们要找到一组在样本空间内.使Loss最大的的对抗样本(该对抗样本由原样本x和经过某种手段得到的扰动项r_adv共同组合得到).这 ...

  4. ICLR 2019计算机视觉、NLP、图模型、对抗学习、表示学习和元学习

    https://www.toutiao.com/a6703123631590867459/ 原作者:Marina Vinyes 深度学习与NLP编译 关键词:Computer Vision, Natu ...

  5. 文本中的对抗学习 + pytorch实现

    最近,微软的FreeLB-Roberta [1] 靠着对抗训练 (Adversarial Training) 在GLUE榜上超越了Facebook原生的Roberta,追一科技也用到了这个方法仅凭单模 ...

  6. 对抗学习总结:FGSM->FGM->PGD->FreeAT, YOPO ->FreeLb->SMART->LookAhead->VAT

    对抗训练基本思想--Min-Max公式 中括号里的含义为我们要找到一组在样本空间内.使Loss最大的的对抗样本(该对抗样本由原样本x和经过某种手段得到的扰动项r_adv共同组合得到).这样一组样本组成 ...

  7. 对抗学习常见方法代码实现篇

    原理篇可参考: 对抗学习概念.基本思想.方法综述 FGM 类定义 class FGM():def __init__(self, model):self.model = modelself.backup ...

  8. NLP深度学习:近期趋势概述

    NLP&深度学习:近期趋势概述 https://www.cnblogs.com/DicksonJYL/p/9686204.html 摘要:当NLP遇上深度学习,到底发生了什么样的变化呢? 在最 ...

  9. NLP深度学习:近期趋势概述 1

    摘要:当NLP遇上深度学习,到底发生了什么样的变化呢? 在最近发表的论文中,Young及其同事汇总了基于深度学习的自然语言处理(NLP)系统和应用程序的一些最新趋势.本文的重点介绍是对各种NLP任务( ...

最新文章

  1. 你值得拥有!一个基于 Spring Boot 的API、RESTful API 的项目
  2. 函数的方法call、apply、bind
  3. 弹性碰撞后速度方向_两物体发生弹性碰撞后.相对速度大小不变.方向相反. ,也可以说两物体的速度之和保持不变.即 ....
  4. Azure DevOps+Docker+Asp.NET Core 实现CI/CD(一 .简介与创建自己的代理池)
  5. NOIP2007 count 统计数字
  6. vue怎么使用php调取数据,vue 数据操作
  7. padding、margin百分比
  8. WrapperClass
  9. 【HDU - 4565】So Easy!【数学思维题】
  10. 程序员必会10种算法
  11. 计算机对教育的重要性 英语作文,关于教育的英语作文 教育重要性英语作文!
  12. 微信上传临时素材|微信公众号发送图片
  13. echarts的x轴去掉网格线
  14. 计算机应用oas,办公自动化系统(OAS)
  15. 使用stream将List转换为用逗号拼接的字符串
  16. 2020年最鼓舞人心的句子
  17. Quartus ii 与 Verilog入门教程(1)——Verilog实现8位计数器
  18. 爬取12306站点信息
  19. 小伙整容成雷锋后亮相,网友:快做好事去吧
  20. RabbitMQ高级之如何保证消息可靠性?

热门文章

  1. 95后们,为什么你借不到钱了?
  2. 4个有影响力的绩效管理最佳实践
  3. DWORD类型与16进制字符串之间的相互转换
  4. linux 上 hexo搭建个人博客
  5. Python cmd进入文件夹目录指令
  6. 按照.fmt格式bcp数据文件
  7. 华为服务器mib文件升级固件,SNMP MIB 固 件 升 级
  8. C++使用curl下载文件(get请求)
  9. Unity_场景烘培技术
  10. 《人是会思想的芦苇》——帕斯卡尔