PERT:一种基于乱序语言模型的预训练模型

每天给你送来NLP技术干货!


来自:NLP工作站

作者:刘聪NLP

写在前面

今天分享给大家一篇哈工大讯飞联合实验室的论文,一种基于乱序语言模型的预训练模型-PERT,全名《PERT: PRE-TRAINING BERT WITH PERMUTED LANGUAGE MODEL》。该篇论文的核心是,将MLM语言模型的掩码词预测任务,替换成词序预测任务,也就是在不引入掩码标记[MASK]的情况下自监督地学习文本语义信息,随机将一段文本的部分词序打乱,然后预测被打乱词语的原始位置。

PERT模型的Github以及对应的开源模型其实年前就出来了,只是论文没有放出。今天一瞬间想起来去看一眼,这不,论文在3月14号的时候挂到了axirv上,今天分享给大家。

paper:https://arxiv.org/pdf/2203.06906.pdf
github:https://github.com/ymcui/PERT

介绍

预训练语言模型(PLMs)目前在各种自然语言处理任务中均取得了优异的效果。预训练语言模型主要分为自编码和自回归两种。自编码PLMs的预训练任务通常是掩码语言模型任务,即在预训练阶段,使用[MASK]标记替换原始输入文本中的一些token,并在词汇表中恢复这些被[MASK]的token。

常用预训练语言模型总结:https://zhuanlan.zhihu.com/p/406512290

那么,自编码PLMs只能使用掩码语言模型任务作为预训练任务吗?我们发现一个有趣的现象“在一段文本中随机打乱几个字并不会影响我们对这一段文本的理解”,如下图所示,乍一看,可能没有注意到句子中存在一些乱序词语,并且可以抓住句子的中心意思。该论文探究了是否可以通过打乱句子中的字词来学习上下文的文本表征,并提出了一个新的预训练任务,即乱序语言模型(PerLM)。a87d70e63becdab606f4d034dcbf869d.png

模型

PERT模型结构如上图所示。PERT模型结构与BERT模型结构相同,仅在模型输入以及预训练目标上略有不同。

PERT模型的细节如下:

  • 采用乱序语言模型作为预训练任务,预测目标为原始字词的位置;

  • 预测空间大小取决于输入序列长度,而不是整个词表的大小(掩码语言模型预测空间为词表);

  • 不采用NSP任务;

  • 通过全词屏蔽和N-gram屏蔽策略来选择乱序的候选标记;

  • 乱序的候选标记的概率为15%,并且真正打乱顺序仅占90%,剩余10%保持不变。

由于乱序语言模型不使用[MASK]标记,减轻了预训练任务与微调任务之间的gap,并由于预测空间大小为输入序列长度,使得计算效率高于掩码语言模型。PERT模型结构与BERT模型一致,因此在下游预训练时,不需要修改原始BERT模型的任何代码与脚本。注意,与预训练阶段不同,在微调阶段使用正常的输入序列,而不是打乱顺序的序列。

中文实验结果与分析

预训练参数

  • 数据:由中文维基百科、百科全书、社区问答、新闻文章等组成,共5.4B字,大约20G。

  • 训练参数:词表大小为21128,最大序列长度为512,batch大小为416(base版模型)和128(large版模型),初始学习率为1e-4,使用 warmup动态调节学习率,总训练步数为2M,采用ADAM优化器。

  • 训练设备:一台TPU,128G。

机器阅读理解MRC任务

在CMRC2018和DRCD两个数据集上对机器阅读理解任务进行评测,结果如下表所示。10d5d199ed8c7f6f11ef79482cf2c949.pngPERT模型相比于MacBERT模型有部分的提高,并且始终优于其他模型。

文本分类TC任务

在XNLI、LCQMC、BQ Corpus、ChnSentiCorp、TNEWS和OCNLI 6个数据集上对文本分类任务进行评测,结果如下表所示。efa1fd68b6164b090614db33893cdfde.png在文本分类任务上,PERT模型表现不佳。推测与MRC任务相比,预训练中的乱序文本给理解短文本带来了困难。

命名实体识别NER任务

在MSRA-NER和People’s Daily两个数据集上对命名实体识别任务进行评测,结果如下表所示。feab0ad9af7be0b517ec30ccb514fab6.pngPERT模型相比于其他模型均取得最优的效果,表明预训练中的乱序文在序列标记任务中的良好能力。

对比机器阅读理解、文本分类和命名实体识别三个任务,可以发现,PERT模型在MRC和NER任务上表现较好,但在TC任务上表现不佳,这意味着TC任务对词语顺序更加敏感,由于TC任务的输入文本相对较短,有些词语顺序的改变会给输入文本带来完全的意义变化。然而,MRC任务的输入文本通常很长,几个单词的排列可能不会改变整个文章的叙述流程;并且对于NER任务,由于命名实体在整个输入文本中只占很小的比例,因此词语顺序改变可能不会影响NER进程。

语法检查任务

在Wikipedia、Formal Doc、Customs和Legal 4个数据集上对文本分类任务进行评测语法检查任务进行评测,结果如下表所示。f8eb7d123c436f34b36d68a6cebb3227.pngPERT模型相比于其他模型均取得最优的效果,这是由于下游任务与预训练任务非常相似导致的。

预训练的训练步数对PERT模型的影响

不同的下游任务的最佳效果可能出现在不同的预训练步骤上,如下图所示。b39058463c6fc9d760b43bc3beb3abce.png我们发现对于MRC和NER任务,随着预训练步数的增加,下游任务也会随之提高。然而,对于TC任务,不同数据的指标在不同的步数上取得最优。如果考虑到特定任务的效果,有必要在早期训练中保存部分模型。

不同的打乱粒度对PERT模型的影响

不同粒度间的打乱,可以使使输入文本更具可读性。通过在不同粒度内乱序输入文本来比较性能,如下表所示。d3fed3636db10c2e99a2601b70126e0b.png我们发现,在各种打乱粒度中,无限制乱序的PERT模型在所有任务中都取得了最优的效果;而选择最小粒度(词语之间)的模型,效果最差。可能原因是,虽然使用更小的粒度的乱序可以使输入文本更具可读性,但是对预训练任务的挑战性较小,使模型不能学习到更好地语义信息。

不同预测空间对PERT模型的影响

将PERT模型使用词表空间作为预测目标是否有效?如下表所示。ef69ffe7ce50fe38db616a2923e830dc.png实验结果表明,PERT模型不需要在词表空间中进行预测,其表现明显差于在输入序列上的预测;并且将两者结合的效果也不尽如人意。

预测部分序列和预测全部序列对PERT模型的影响

ELECTRA模型的实验发现预测完全序列的效果比部分序列的更好,因此ELECTRA模型采用RTD任务对判别器采用完全序列预测。但通过本论文实验发现,预测完全序列在PERT模型中并没有产生更好的效果。表明在预训练任务中使用预测全部序列并不总是有效的,需要根据所设计的预训练任务进行调整。b8d5dfd367cda83d3bd31a2e61f6f38c.png

总结

PERT模型的预训练思路还是挺有意思的,并在MRC、NER和WOR任务上均取得了不错的效果。并且由于结构与BERT模型一致,因此在下游任务使用时,仅修改预训练模型加载路径就实现了模型替换,也比较方便。当打比赛或者做业务时候,可以不妨试一试,说不定有奇效。(ps:我在我们自己的MRC数据集上做过实验,效果不错呦!!)


最近文章

EMNLP 2022 和 COLING 2022,投哪个会议比较好?

一种全新易用的基于Word-Word关系的NER统一模型,刷新了14种数据集并达到新SoTA

阿里+北大 | 在梯度上做简单mask竟有如此的神奇效果


下载一:中文版!学习TensorFlow、PyTorch、机器学习、深度学习和数据结构五件套!  后台回复【五件套】
下载二:南大模式识别PPT  后台回复【南大模式识别】
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于CIFAR模型实现DeepFool图像攻击算法的代码实现。请注意,此代码仅用于演示目的,实际应用中需要进行更多的优化和调整。 ```python import numpy as np import torch import torch.nn as nn import torchvision.transforms as transforms from PIL import Image # 加载预训练的CIFAR模型 model = torch.hub.load('chenyaofo/pytorch-cifar-models', 'cifar10_resnet20', pretrained=True) model.eval() # 定义DeepFool算法 def deepfool(image, net, num_classes=10, overshoot=0.02, max_iter=50): """ :param image: 输入的图像 :param net: 预训练的模型 :param num_classes: 分类数 :param overshoot: 步长 :param max_iter: 最大迭代次数 :return: 扰动后的图像和扰动大小 """ # 将图像转换为张量 image = transforms.ToTensor()(image).unsqueeze(0) # 将模型转换为eval模式 net.eval() # 计算初始类别 f_image = net.forward(image).data.cpu().numpy().flatten() I = (np.array(f_image)).flatten().argsort()[::-1] # 初始化扰动 pert_image = image.clone() w = np.zeros(image.size()) # 迭代 k_i = I[0] iteration = 0 while k_i == I[0] and iteration < max_iter: # 计算梯度 x = pert_image.clone().detach().requires_grad_(True) fs = net.forward(x) pert = torch.Tensor([0.0]).cuda() grad_orig = torch.zeros(fs.size()).cuda() grad = torch.zeros(fs.size()).cuda() for i in range(num_classes): if i == I[0]: grad_orig[:, i] = torch.autograd.grad(fs[:, i], x, retain_graph=True)[0] else: grad[:, i] = torch.autograd.grad(fs[:, i], x, retain_graph=True)[0] # 计算最小扰动 for i in range(1, num_classes): if k_i != I[i]: p_i = (grad_orig - grad[i]).data.cpu().numpy() pert_i = abs(p_i).max() / np.linalg.norm(p_i.flatten()) if pert_i < pert: pert = pert_i w = p_i # 更新扰动 r_i = (1 + overshoot) * w pert_image = image + torch.from_numpy(r_i).float() pert_image = torch.clamp(pert_image, 0, 1).detach() f_pert_image = net.forward(pert_image).data.cpu().numpy().flatten() I = (np.array(f_pert_image)).flatten().argsort()[::-1] # 更新迭代次数和目标类别 k_i = I[0] iteration += 1 # 计算扰动大小 pert = np.linalg.norm((pert_image - image).numpy().flatten(), ord=2) return pert_image, pert # 加载图像并应用DeepFool算法 image = Image.open('example.jpg') pert_image, pert = deepfool(image, model) # 保存扰动后的图像 transforms.ToPILImage()(pert_image.squeeze()).save('perturbed_image.jpg') ``` 以上是一个基于CIFAR模型实现DeepFool图像攻击算法的实现,该算法可以生成一些误导性的扰动,从而欺骗神经网络对图像进行错误分类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值