最近的深度学习圈子,NLP社区无疑是最热闹的,各种“碾压BERT”,“横扫排行榜”新闻满天飞,确实人家媒体就是靠点击量吃饭的嘛所以也不要太过苛刻。即便如此,也需要我们自己有独立思考的能力,虽然是被标题吸引进来的,但是对于每个模型我们都需要静下来好好思考。之前博客是有解析了一些BERT的后起之秀,比如ERNIE-Baidu,ERNIE-THU,XLMs,MASS, UNLIM等等,这篇博客呢就是带大家整理一下在那之后NLP社区发生的一些事…
这篇文章(准确说是技术报告)的重点可以从标题一眼看出:Whole Word Masking和Chinese BERT。
首先让我们回想一下vanilla BERT的mask策略,对于一个输入首先是进行分词(WordPiece Tokenizer),接着随机地对输入进行mask,最后利用MLM任务去训练模型。
解释一下WordPiece Tokenizer(主要是为了去除未登录词对模型效果的影响),举个栗子,对于英文输入
unaffable
,分词结果就是["un", "##aff", "##able"]
;而对于中文,则是直接按字切分。
那么这样做会导致什么结果呢?大概就是模型只能死板地记住每个词中字母的出现顺序,而不能理解词语的语义。所以最直接的做法就是把整个短语进行mask,也就是这里的全词掩码。其实关于mask的范围,在这篇文章之前就有过BERT+N-gram masking,有过百度的ERNIE,BERT原创团队也是提出了Whole Word Masking(只不过是在英文数据上的)。所以的话这篇技术报告也是注重在对比ERNIE/BERT和WWM-BERT三者的模型效果上。
虽然WWM-BERT-ZH只是在原始的BERT上修改的不多,但是按照惯例我们还是简单介绍一下模型训练的细节。
作为模型效果对比的下游任务,作者选取了sentence-level到document-level的以下几个任务:
okay,关于模型对比的具体结果这里篇幅有限就不贴上来了,大家感兴趣的可以点击标题超链接去文章里看。粗略统计了一下,六项比对任务中,ERNIE赢得四项,WWM-BERT-ZH赢得两项,BERT-ZH…
和Whole Word Masking BERT以及ERNIE类似,SpanBERT这里也是选择对原始BERT的mask策略进行调整,不过前者是在phrase/entity的级别进行mask,而spanBERT则是选择了更长的范围进行mask,试验结果指出该种策略会对span selection任务有较明显的提高,比如问答、指代消解等。相比于原始BERT,这里创新点可以认为是以下两点:
mask策略
:随机mask span,而不是token预训练目标
:为了与新提出的mask策略相匹配,提出了span-boundary objective (SBO);同时发现NSP对下游任务的表现并不好,果断抛弃。okay,让我们来看看这个span masking和SBO到底是怎么实现的。
对于输入 X = ( x 1 , … , x n ) X=\left(x_{1}, \ldots, x_{n}\right) X=(x1,…,xn),span masking的具体做法是:首先通过几何分布 ℓ ∼ Geo ( p ) \ell \sim \operatorname{Geo}(p) ℓ∼Geo(p)采样出span的长度,然后随机选择span的起始位置。如此迭代进行,直到采样出的span长度达到15%的输入长度。作者设置 p = 0.2 p=0.2 p=0.2并且丢弃长度大于10的span(确实呀把十个单词都给抹去,还要求模型预测出来,这有点过分了),经过计算最后得出span的平均长度为3.8个单词,注意这里的单词是完整的单词而不是subword。
那么span masking相对于之前的全词masking以及entity masking效果怎么样呢?作者在ablation study中也对其进行了验证。挑选了几种不同的masking策略进行对比,除了指代消解任务,其他下游任务中span masking都表现出更好的效果。
SBO的思想就是通过已知的边界去预测未知的被mask掉的那些token。具体而言,对于一个span ( x s , … , x e ) \left(x_{s}, \ldots, x_{e}\right) (xs,…,xe),其中 x s x_s xs和 x e x_e xe分别是span的起始和终止位置。对于每一个被mask的词,SBO使用span起始位置的前一个token x s − 1 x_{s-1} xs−1和终止位置的后一个token x e + 1 x_{e+1} xe+1以及被mask掉token的位置向量 p i p_{i} pi来表示该token:
y i = f ( x s − 1 , x e + 1 , p i ) \mathbf{y}_{i}=f\left(\mathbf{x}_{s-1}, \mathbf{x}_{e+1}, \mathbf{p}_{i}\right) yi=f(xs−1,xe+1,pi) h = LayerNorm ( GeLU ( W 1 ⋅ [ x s − 1 ; x e + 1 ; p i ] ) ) \mathbf{h}=\text { LayerNorm }\left(\operatorname{GeLU}\left(W_{1} \cdot\left[\mathbf{x}_{s-1} ; \mathbf{x}_{e+1} ; \mathbf{p}_{i}\right]\right)\right) h= LayerNorm (GeLU(W1⋅[xs−1;xe+1;pi])) f ( ⋅ ) = LayerNorm ( GeLU ( W 2 ⋅ h ) ) f(\cdot)=\text { LayerNorm }\left(\operatorname{GeLU}\left(W_{2} \cdot \mathbf{h}\right)\right) f(⋅)= LayerNorm (GeLU(W2⋅h))
举个栗子可以看下图,最终的模型是将MLM和SBO两个损失相加进行训练。
其实这里就是对原始BERT中NSP任务的解读,在作者们的实验中发现不使用NSP进行预训练得到的模型效果反而更好,即Single-Sequence Training,下表中2seq表示segment_a + segment_b
的输入形式
推测可能是由于(a)长度更长的完整文本包含信息更全;(b)从另一个文档中选取下一句会对模型引入噪声。
可以看到,之前的预训练模型都是在BERT的基础上修改一些小组件,数据集啊预训练目标啊但是整体还是属于BERT派的。但是在这篇文章里,谷歌和CMU又放出了一个新的模型XLNet,果然…又屠榜了…首先数据和算力比BERT多是一个原因,另外一个的话也是找到了BERT中的一些缺点然后改进它导致的。
PS. 关于XLNet的解读网上现在已经有很多了,所以这里我仅仅列举比较重要的几个方面,可能捎带几句不会太具体,这一节reference部分会给出个人认为比较好的解读参考~
文章一开始就把大规模预训练模型分为两类autoregressive (AR) 和autoencoding (AE)。简单而言,自回归语言模型就是自左向右或者自右向左地对文本进行语言建模,它的好处是对生成任务有天然的优势,缺点呢就是只能得到单向的信息不能同时利用上下文的信息。而自编码就是类似BERT那样的通过[MASK]标记来获取前向和后向的信息。
文章主要指出了BERT模型的几点不足:
为了改进上面BERT的缺陷,同时利用其AR和AE模型的优势,这就诞生了XLNet。那么XLNet到底是怎么做的呢?
看了一眼RoBERTa的作者和前面SpanBERT的作者基本都是一样的…可以…这都不是重点!重点是-----XLNet屠榜了,BERT坐不住了,文章指出BERT是完完全的underfit,于是他们又对BERT进行了一次改造计划,当然,最终结果又是:屠榜。恭喜BERT重回榜首
Our training improvements show that masked language model pretraining, under the right design choices, is competitive with all other recently published methods.
整理了一下RoBERTa相比原始BERT模型的新的配方:
在原始的BERT实现中,mask操作是在数据预处理的时候就完成的,这样在每个训练epoch中数据的mask位置都是相同的,这显然是不太合适的。而动态mask则是对于每一个输入都生成一次新的mask,这对于更大训练数据集/更大训练步数是很重要的。实验结果如下,dynamic masking效果是比static好了一点点,但是四舍五入等于一样…
同XLNet/SpanBERT一样,作者在这里也是发现NSP任务对下游任务并不会起到帮助甚至有点小危害,
本文压轴留给国产模型ERNIE2.0。Baidu团队之前发布的ERNIE1.0效果就不错,虽然基础框架沿袭BERT,但是训练语料以及mask策略的改进,使其在中文任务上表现更好。这刚过了几个月,又发布了增强版的ERNIE,最近NLP社区更新速度可见一斑。
先前的模型比如ELMO、GPT、BERT、ERNIE1.0、XLNet等都是基于词和句子的共现关系来训练的,这导致模型不能够很好地建模词法、句法以及语义信息。为此,ERNIE2.0提出了通过不断增量预训练任务进行多任务学习来将词法句法以及语义信息融入到模型当中去。整体流程如下所示,首先利用简单的任务初始化模型,接着以串行的方式进行持续学习(Continual Learning),对于每次新增的训练任务,模型可以利用之前已经训练过的任务信息去更好地学习新任务,这跟人类的学习方式是一样的。
整体框架还是基本跟ERNIE1.0的一样,不过ERNIE2.0为了匹配多任务持续学习的理念,需要在输入的时候额外增加一部分Task Embedding,用来告诉模型这是在处理哪个任务。
前面说到要让模型获取词法、句法以及语义的信息,那么怎么设计合适的预训练任务就成了非常重要的一环。其实BERT本身也可以看做是多任务(MLM+NSP),然后对于扩展BERT至多任务,MTDNN也有过尝试,使用了GLUE相似的任务进行训练然后在GLUE上SOTA了。不过ERNIE2.0与MTDNN在任务设计上不同的是,在预训练阶段使用的任务基本都是无监督或者是弱监督的。要知道在NLP中有标注的数据不多,但是无标注的数据可以说是源源不断,如果能好好利用起来简直功德圆满。okay,下面我们来介绍一下具体的任务设计
基于单词的预训练任务用于获取词法信息
主要是用于建模句法信息
主要用于建模语法信息
query+title
,输出为标签,其中“0”表示这两个是强相关的(定义为用户点击的结果条目),“1”表示弱相关(定义为搜索返回结果中不被用户点击的条目),“2”表示不相关(定义为没有出现在返回结果里的条目)okay,介绍完模型,我们来看看效果怎么样~ERNIE2.0以及BERT在GLUE上的表现,可以看出在所有任务上ERNIE2.0的效果都超过了原始的BERT和XLNet。但是有一点就是我去GLUE Leadboard上瞄了一眼,好像并没有看到ERNIE2.0的身影,不知道为什么还没有提交上去?
这是中文数据集上的模型比对效果,目前中文版的模型好像还没有发布出来~
不知道大家有没有get到题目的小彩蛋呢哈哈哈~ N.L.P—>Nvidia League Player可以说是非常准确地概括了现在的NLP发展趋势。
以上
2019.08.11