BERT及其变种们

Transformer-XL

买衣服都知道XL是比large更大一号,所以Transformer-XL也是比Bert更大一号。
大在哪呢?
Bert的模型默认是长度512的输入,如果是QA匹配问题, 那一个句子只有256个空间,还不算各种token占位。
而这种复杂模型用来训练这么少的输入,属实可惜。 如果扩充输入,那就是扩充参数量,而参数量就是钱,参数太多是训练不起的。
所以Transformer-XL说Bert小,然后给自己起名XL。它解决了输入长度的限制问题。

假如用Bert给2000长度的句子做序列标注:
1.训练。 Bert需要把句子切成4份再单独训练。
2.预测。 Bert先输入[0:512]个token,再输入[1:513]个token,一点点挪着预测出标注。
缺点很明显,训练时句子切完语义就不连贯了,预测时一个一个挪很费时间。

Transformer-XL这样改进:
该切还是切,但我要求

  1. 训练时,模型能把 i − 1 i-1 i1段的信息加入 i i i段的训练中。但反向传播时,因为被切割了,所以训练 i i i时不给 i − 1 i-1 i1段做训练。计算Multi-head时,只对k和v用拼接后的参数,而q因为代表本身的query,所以只用本身的参数。
  2. 预测时,很明显能看出重新计算是有缺陷的。只要保存上一段的状态,下一段是可以整段直接算出来的,就像训练时一样。
    实际上,你可以不只保存 i − 1 i-1 i1段,多往前保存几段更好了,只要缓存够用。

XLNet

这个是融合了GPT和Bert两家的模型。

  1. GPT是自编码模型, 通过双向LSTM编码提取语义。
  2. Bert是自回归模型,不分前后,一坨扔进去,再用attention加强提取语义的效果。
  3. XLNet融合了Bert的结构和GPT的有向预测,具体做法有点抽象,请耐心。

首先,XLNet觉得Bert给的任务太简单了。Bert是Mask language model,举例说明,假如Bert顺序输入abcd四个词,Bert会随机mask掉一部分词,假设mask成了ab[mask]d,接下来Bert要根据这个mask序列预测mask位置的词"c"。
XLNet认为不该一下子把所有词都告诉网络,可以先告诉网络第一个词是a,然后预测一下,再告诉网络一二位置的词是ab,再预测一下,最后告诉网络一二四位置的词是abd,再预测一下。这样力求网络能以最少的信息预测出结果。更有甚者,可能先告诉b,再告诉bd,再告诉abd.

为了实现上面的训练方式,XLNet这样做:
对于序列abcd,先

  1. 给其加上position embedding. 文字不好表述,就是加了一维位置向量。
  2. 随机打散,可能变成bcda, 可能变成adbc. 这里以adbc为例。
  3. 根据a->d->b->c这个序列,我们预测a时什么都看不到,预测d时能看到a,预测b时能看到ad,预测c时能看到adb。我们调换一下顺序:a:None,b:ad,c:abd,d:a。这四种情况就对应了上述在分别mask掉a、b、c、d时的某一种情况。我们完全可以根据原始的输入"abcd"再加上01的掩码获得上述情况下的各种输入,即a位置掩盖所有,b位置掩盖c,c位置不掩盖,d位置掩盖bc。如果是自监督学习,就自己掩盖自己,如果是任务学习,就不掩盖自己。
    总之,使用这种掩码机制可以等效为mask机制+序列预测的难度加强版。因为掩码机制使用矩阵,看着很像attention,就蹭个热度。又加之网络本身有自己的标准attention,故得名“双流attention”.

通过掩码机制,可以省略添加mask标记的过程,而众所周知mask标记会些许干扰语义模型的表示,所以XLNet算是解决了这个问题。

fastBERT

你是否纠结于Bert的层数太多,输出耗时太长?普通的知识蒸馏又会损失精度?
试试fastBERT吧。
众所周知,Bert的decoder有很多层,但可以肯定,有些问题肯定不需要那么多层,可能只需要浅层的decode特征就足以获得结果。
以分类任务举例,fastBERT这样做:

  1. 获取某一版的Pre-training Bert.
  2. 最后一层加上任务所需的分类网络,对Bert进行fine-tune。
  3. 开始蒸馏,固定Bert主干的参数。在每一层decoder后都加上分类网络,注意这些网络是不共享参数的,各分各的。利用最后一层输出的分类概率,作为中间每一层分类的目标分布,利用KL散度或JS散度做分布拟合。

为什么不用真实标签而是最后一层的输出当目标呢?
因为loss变了,而且此时可以使用没标签的数据做蒸馏。

使用时,将数据输入,先获得第一层decoder,计算分类的不确定度Uncertainty(具体计算公式去找论文)。如果不确定度达标,就以这一层的结果为输出,否则再计算下一层。论文里用“speed”代表不确定性阈值,阈值越大网络更容易在低层就输出。

RoBERTa

这个模型还是Bert,但改了训练目标和参数。
Bert当初训练的时候有俩任务,一个是MLM,另一个是NSP,next sentence prediction,具体做法是输入时输入句对(A,B),判断B是不是A的下一句话。

现在发现,nsp没啥卵用,就把nsp任务删了。

Bert训练MLM是选择句子里15%的词mask,且80%替换为[mask]标记,10%不变,10%替换为其他词。但这15%的词选中就不变了。

RoBERTa说不行。他把数据复制了10份,分别做mask,并保持总训练epoch不变,即每份数据训练原先epoch数的10%。

RoBERTa还借鉴了机器翻译中的trick,提高batch-size能提高模型优化效率和模型性能。

ALBERT

ALBERT是紧跟着RoBERTa出来的,也是针对Bert的一些调整,重点在减少模型参数,对速度倒是没有特意优化。

  1. word embedding太大
    不需要花哨的解释,word embedding设置多大见仁见智,适当就好。ALBERT试验发现原先的300确实没必要,可以适当缩减,对网络没影响。
    但尴尬的是在SST-2数据集上768比256尺寸效果好得有点多,这就有点打脸了。
  2. 参数共享
    在Bert里encoder可以共享层参数,也可以共享attention。
    ALBERT选择全都共享。自身比较来看带共享会降2%的准确率。与Bert相比,无论是base还是large,xlarge,效果都要低一点。值得注意的是Bert在xlarge时效果下降很大,因为模型震荡很厉害,ALBERT因为参数共享,震荡的空间不大,所以准确率随着模型增大依然能稳步上升。
  3. 新任务SOP(sentence-order prediction句子语序预测)
    RoBERTa已经给NSP任务判死刑了。
    NSP任务是输入两个连续的句子,判断他们是不是连续的,而负例是将后一句换成其他文章里的任意句子。如果是这么个负例产生方法, 与其说这个任务是判断连续性,还不如说是先判断俩句子是一个主题(即一个文章),再判断是句子连续。这么一拆,就可以发现,判断主题相同是极简单的任务,且MLM就有类似的功能,所以不需要学习。而判断句子连续倒是有价值。
    所以ALBERT为了只学习句子连续性,就重新设计了任务SOP:正例依然是一篇文章的连续语句,负例却是将两句调换位置。
    数据显示,NSP任务提升模型0.2%,SOP任务提升了1.1%。
  4. 移除dropout
    我在之前分析过dropout的功能。神经网络相比于机器学习模型,优点在于可回归的空间很大,模型的自由度很高,这就让网络可以把自己变得很复杂以最小化loss。因为模型复杂,所以少哪一个神经元都是对模型的致命打击。针对这点设计出dropout,就是告诉模型,不要把自己变复杂,否则用上dropout之后效果比简单模型还要糟糕。
    但这叫做打压式教育,不提倡。既然过拟合的本质是模型过于自由,那就限制自由好了。ALBERT的第2点:参数共享,大大减小了参数量,本身就极大限制了模型的发挥空间,所以既然已经达到了抑制过拟合的目的,也就不需要画蛇添足地加上dropout了。

·····
今天先写这么多
·····

你可能感兴趣的:(BERT及其变种们)