文章目录
背景基础知识FGMPGDFree adversarial trainFreeATYOPOFreeLB背景
我们知道,对抗学习最初在生成模型中应用,比如最简单的GAN,能够生成以假乱真的图像等;后来该模型被用于判别模型中,因为普通的图像分类器泛化能力差,易受攻击导致分类错误,通过增加对抗训练,能够有效提高模型的鲁棒性,同时也能提高模型的泛化能力。
对抗训练中关键的是需要找到对抗样本,通常是对原始的输入添加一定的扰动来构造,然后放给模型训练,这样模型就有了识别对抗样本的能力。其中的关键技术在于如果构造扰动,使得模型在不同的攻击样本中均能够具备较强的识别性。
本文针对自然语言中的对抗学习,针对攻击的“一阶扰动”场景,总结了最近的工作进展,涉及到的知识包括:基本单步算法FGM,“一阶扰动”最强多步算法PGD,以及针对时耗等改进的FreeAT,YOPO和FreeLB,其中FreeLB成为了目前刷榜的SOA。
基础知识
对抗训练,简单来说,就是在原始输入样本x加上一个扰动 radvr_{adv}radv,得到对抗样本后,用其进行训练,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[radv∈SmaxL(θ,x+radv,y)]−−−(1)
该公式分为两个部分,一个是内部损失函数的最大化,一个是外部风险的最小化。
内部max,L为定义的损失函数,S为扰动的空间,此时我们的目的是求得让判断失误最多情况下扰动的量,即求得最佳的攻击参数;外部min,针对上述的攻击,找到最鲁邦的模型参数,也就是防御,进一步优化模型参数,使得在整个数据分布的期望还是最小。
至于公式(1)的定义是否合理,内部通过max优化找到对抗样本是否足够,遇到其他的对抗样本模型是否依然鲁棒?Madry在论文中给了证明,并认为:通过PGD优化找到的对抗样本,将其进行训练使得在这些对抗样本上神经网络的loss很小,那么这个神经网络也就可以抵抗其他的对抗样本,并且说针对内部非凸的优化,PGD能够成功将其解决。
FGM
在PGD提出之前,Goodfellow 在提出FGM,其增加的扰动为:
radv=ϵ⋅g/∣∣g∣∣2g=▽xL(θ,x,y)r_{adv} = \epsilon \cdot g/||g||_2\\ g = \triangledown_x L(\theta,x,y)radv=ϵ⋅g/∣∣g∣∣2g=▽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=Π∣∣radv∣∣F≤ϵ(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=r∈Rd, ∣∣r∣∣2≤ϵ为扰动的约束空间,α为小步的步长||r||_2 \leq \epsilon为扰动的约束空间,\alpha为小步的步长∣∣r∣∣2≤ϵ为扰动的约束空间,α为小步的步长,这里Π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 = 3for 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_x▽x在外层,需要一次前后后向传播算法,得到一个关于神经网络参数θ\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 XB⊂X 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)gadv←▽xl(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*nm∗n次,并且其能够灵活地增加n并且减少m来通过更少的计算消耗获取同样的效果。经验上,如果要获取与PGD-K同样的效果,YOPO需要m∗nalitterlargerm*n \;a \;litter\; largerm∗nalitterlarger的设置。
另外,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=1∑m▽θ(i=1∑Bl(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 XB⊂X do
δ0←1(Nθ)U(−ϵ,ϵ)\delta_0\leftarrow \frac{1}{\sqrt{(N_{\theta})}} U(-\epsilon, \epsilon)δ0←(Nθ)1U(−ϵ,ϵ)
g0←0g_0\leftarrow 0g0←0
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)]gt←gt−1+K1EZ,y∈B[▽θL(fθ(X+δt−1),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+δt−1),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≤ϵ(δt−1+α⋅gadv/∣∣gadv∣∣F)
end for
θ←θ−τgK\theta \leftarrow \theta-\tau g_Kθ←θ−τgK
end for
end for
欢迎关注公众号:
Ref:
Zhang, D., Zhang, T., Lu, Y., Zhu, Z. & Dong, B. You Only Propagate Once: Accelerating Adversarial Training via Maximal Principle. 17.Madry, A., Makelov, A., Schmidt, L., Tsipras, D. & Vladu, A. Towards Deep Learning Models Resistant to Adversarial Attacks. arXiv:1706.06083 [cs, stat] ().Zhu, C. et al. FreeLB: Enhanced Adversarial Training for Language Understanding. arXiv:1909.11764 [cs] ().Shafahi, A. et al. Adversarial Training for Free! arXiv:1904.12843 [cs, stat] ()./jmh1996/article/details/102048395
如果觉得《NLP --- 对抗学习:从FGM PGD到FreeLB》对你有帮助,请点赞、收藏,并留下你的观点哦!