- 全称:Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension。BART来源于Bidirectional and Auto-Regressive Transformers
- 发表时间: 2019.10.29
- 团队:Facebook AI
- Paper地址
- 代码地址
目录
Abstract
1. Introduction
2. Model
2.1 Architecture(模型结构)
2.2 Pre-training BART(预训练)
3. Fine-tuning BART(微调)
3.1 Sequence Classification Tasks(分类任务)
3.2 Token Classification Tasks(Token级别的分类任务)
3.3 Sequence Generation Tasks(文本生成任务)
3.4 Machine Translation(机器翻译)
4. Comparing Pre-training Objectives
4.1 Comparison Objects
4.2 Tasks
4.3 Results
5. Large-scale Pre-training Experiments
BART是一种非常适用与生成式任务的模型,当然它也能完成判别式任务,而且效果也很好。它主要结合了BERT和GPT两种模型思路,使得它不仅具有双向编码的优势,也具有单向自回归编码的优势。本篇主要探讨一下BART的原始论文,如果仅仅想作为了解,看完本篇介绍就够了,但是我还是强烈建议读者读一读原始论文。论文中的每一部分,我这里仅做要点解读。
1)通过随机噪声函数(说白了就是能够制造破坏文档结构的任何方法)来破坏文章结构;
2)逼迫模型能够学会将结构已经被破坏了的文章进行重构,使文章变回原来的样子;
至于如何破坏文章结构呢?作者说了,他们通过评估不同方法后发现采用下列方法效果最好,一个是随机打乱原文句子的顺序,一个是随机将文中的连续小片段(连续几个字或词)用一个[MASK]代替,和Bert不同,Bert是一个词用一个[MASK]替换,BART是连续多个词用一个[MASK]替换。
论文中,作者还仿照其它的预训练模型的方式,对BART进行了消融实验,也就是说,把BERT、XLNet等预训练方法移植到BART中,以此更好的验证哪一些模型的哪一些因素对最终任务的性能影响最大。
这个和摘要中介绍的差不多,总之就是告诉我们BART的训练分两步走:通过随机噪声破坏文章结构,再训练一个序列到序列的模型来重构被破坏的文本。
对于片段式MASK,片段的长度是随机选取的,但实际上也不是随机的,后文有提到,用了泊松分布的方法采样不同长度的片段(包括长度为0)。
这里提到了,BART不仅在生成任务上(NLG)特别有效,同时在自然语言理解任务上(NLU)表现的也很出色。
下面看一些论文提供的BART示意图:
在BART中,它的输入输出并不需要严格的保持长度一致,即Encoder的输入与Decoder的输出不需要对齐。从上述结构图中可以看出,左边部分Encoder接收的结构破坏后的文章,它经过Encoder双向编码,类似于Bert,右边部分接收来自Encoder的输出后,经过自回归解码输出预测结果,类似于GPT(注意GPT是不需要Encoder的)。自回归解码依据的是最大似然概率,这一点和N-Gram词袋模型或者NNLM模型是相似的。作者在上图中还提到了,对于微调,BART的Encoder和Decoder接收同样的输入,且此时的输入文章是没有被破坏了的,这样一来,Decoder最后一维的输出被拿来作为文章的向量表示,类似于Bert,只不过bert用的是Encoder的final hidden state。其实这里作者介绍的笼统了,下文有提到,微调方式是需要依据不同的任务的,这个下文再说。
这一节是重点。
开头作者就精辟的总结了:BART模型的实现本质上仍然是Sequence-to-Sequence范式,实质就是Encoder-Decoder架构,Encoder属于双向编码,对被破坏的文本进行编码;Decoder属于单向解码(left-to-right),也就是自回归解码,解码出我们想要的目标文本。优化目标是负的对数似然函数。
这一段有几个重点:
与此同时,作者指出了BART和BERT的不同:
说实话,个人觉得上述两个differences有点多此一举了,因为BART的Architecture的定位本来就是Full Transformer,自然和BERT就存在上述差别。
BART的预训练目标就是对于被破坏的文章优化一个重构损失函数,实际上就是针对Decoder的预测结果和目标文章(label)的交叉熵损失。亮点是它允许接受任意破坏形式的文章,这个还是挺强的,本人打过一些比赛,输入是一堆关键词,要求输出是基于这些关键词的完整结构的文章,用BART效果挺不错的。作者也指出了,假设极端的情况下,输入完全是空的,那么BART实质上就是一个语言模型,不是很明白作者想说明啥。
下文作者列出了几种具体的打破文章结构的方式:
下面看下作者给出的几种corruption方式的示意图:
一直没太明白,作者开源的模型是这几种corruption的方式都同时用了?还是只用了其中一种或几种。
前文说了,微调的方式根据任务的不同而不同。下面是作者提到的几种任务的微调:
Encoder和Decoder接受了相同的输入,然后取Decoder的输出的最后一个Token的hidden state接上一个分类层进行微调,实际上调的就是这个分类层,思路和BERT的分类任务微调极其相似,但Token的选取是不一样的,BERT中,是在输入序列的第一个位置添加了[CLS]Token,最后输出取得也是这个CLS,而BART是在最后一个位置添加的[CLS],所以最后取得也是最后一个Token,作者认为这样能使最后一个Token的表示参考了前面所有Token的语义信息。个人认为合理与否得看具体实验对比,事实上本身要取哪个Token来表征整个句子都不是写死的。
Token级别的分类任务有实体识别、阅读理解、问答等,均为抽取式。该任务和句子分类类似,只不过这里用到了Decoder输出的每一个Token的hidden state,即对每个Token进行分类。
该任务可以算是BART的强项所在了,由于其模型结构特点,它天然支持序列生成任务,例如抽象问答任务和摘要任务(注意是生成式的非抽取式的),其微调方式也很直接简单,给模型一个原始文本和一个目标文本,编码器接收原始文本,解码器解码出预测文本,并和目标文本求损失。
这个任务比较有意思,作者在BART的Encoder部分做了比较大的改动。
作者将原来BART的Encoder和Decoder看成了一个整体,作为新的Decoder,然后将原来Encoder的词嵌入层(embedding layer)替换成一个新的Encoder,通过新的Encoder将原始外文编码先编码,再送进原始BART的Encoder-Decoder的结构中。猜测作者认为,通过再训练一个新的编码器,并用原来的编码器和解码器统一作为解码器,以此能弥补单纯用一个Decoder造成的Decoder能力不足的缺陷。
微调的时候,作者采取了两步走的策略:第一步先只更新随机初始化的源编码器(即新Encoder)、BART的位置嵌入向量和编码器第一层的自注意输入投影矩阵(原Encoder)。其余参数固定住。第二步少量迭代全部参数。
这一节其实就是对不同类型的语言模型进行了一个对比介绍,包括GPT、XLNet、BERT、UniLM、MASS等,感兴趣的同学可以看下原文。
这一节对一些常见的NLP任务进行了简要的介绍,感兴趣可以读一下原文。
这一节展示了上述不同类型的语言模型在不同任务上以及BART不同随机噪声函数下(即上文介绍的不同文档破坏方法)在不同任务上的实验效果,并进行了对比总结:
根据表格,作者得出了以下几个重要的结论:
总结来说,有以下几点:
这一章讲的是BART-large的预训练实验,我就统一讲一下预训练的实验设置:
作者还在几个不同的生成式任务中进行了进一步实验对比,感兴趣的可以看下原文。这里特别提一下在生成任务中,微调阶段作者用的是smoothed cross entropy loss,平滑因子设置为0.1。在模型推理阶段,作者设置了Beam Search的方式,大小为5,还设置了最小生成长度和最大生成长度以及长度惩罚。
另外,作者还侧面说明了BART更擅长于抽象式生成任务,因为作者发现,如果摘要在原文中有高度相似之处时,不管是抽取式模型还是生成模型,都表现的差不多。
到此为止,事实上BART的核心要点都介绍完了,论文其余的部分仅仅是常规内容,想要全面了解BART的同学,建议读一下原文以及源码。