1. ELMO (2018.2.15)
Elmo是基于双向LSTM,使用经典语言模型的思路训练的。需要先在大量语料上pre-train,可以得到所谓deep contextualized的词向量,然后通过特定的方法结合在不同的NLP任务中。
1.预言模型
对于一个N个词的序列,是通过已知序列来计算的, 所以一个前向的预言模型得到每个token的概率公式如下:
依据上述预言模型,将一句话(每个token用传统独立的word-embedding表示)使用层的LSTM,便可以得到context-independent 的representation。
在这个层的LSTM中,对应的token representation有 。LSTM的顶层输出 h^{LM}_{k,L}使用一个Softmax层来预测下一个词$$t_{k+1}。
上述是前向的LSTM,反向的LSTM是相同的思路:
训练的时候同时最大化前向和后向的似然概率。
其中词向量与Softmax层参数是共享的,前向LSTM和后向LSTM训练各自的参数。
2.Elmo
对于一个层的双向LSTM,每个token 可有有各向量表示:
对每一层, 等于j层前向和后向向量concat在一起得到。
ELMO将多层的biLSTM的输出整合为一个向量,最简单的情形是,ELMo只使用顶层的向量 。
但是,据称最好的ELMo模型是将所有biLSTM的输出加上normalized的softmax学出来权重,这个有点想attention的原理。
其中, 是缩放因子,相当于把做使用之前对每一层biLSTM用了layer normalization:
3.接入下游任务方法
(1)直接将ELMo词向量与普通的词向量拼接(concat)。 (2) 直接将ELMo词向量与隐层输出向量 拼接 ,在SNLI,SQuAD上都有提升。
2. GPT, GPT2.0, GPT3.0
GPT是比Bert更早的预训练预言模型,也是pre-train+fine-tuning模式的开创作品。但是GPT的各个版本都是用的单向预言模型。并且使用transfomer解码器。
- GPT1.0
如上图所示,GPT模型结构就是由12个Transformer解码器堆叠而成。 在fine-tuning阶段的模型输入,使用Start,Delim, Extract拼接。
- GPT 2.0 模型结构和预训练方式预GPT1.0本质上相同。不同处:
- 使用更大的语料和质量更好的语料。
- zero shot的实验设置,不在强调使用fine-tuning.
- 更大的模型。
- GPT 3.0 几个关键点:
- 更大的模型
- 不在需要fine-tuning
- 使用Few-shot的实验设定效果最好。
- 任然是用Transformer实现的单向预言模型。
2. BERT (2018.10.11)
Bert是使用Transformer作为组件,同时在两个supervised的任务上联合训练、收敛。这两个任务是预测Mask词和预测两句话关系,第一个任务可以看作模型学习token-level的信息,并且是双向的。第二个任务是学习sentence-level甚至doc-level的信息。下面分层来讲解:
- Input/Output Representations
使用一个sentence-pair {A ,B} 来构造输入,用[SEP]来连接,并以[CLS]开头,[CLS]其对应的最后一层的hidden state可以用来做句子分类任务。构造一个input representation使用三层的编码的和:
- WordPiece embeddings来构造token embedding
- 用来表示某个token属于句子A还是句子B,称作Segment Embedding。
- position embeddings,学习出来的embedding向量。
- Pre-training BERT
- 2.1 Pre-training Task 1#: Masked LM(masked language model)
因为传统的 conditional language models只能 left-to-right 或者right-to-left的学习,所以,为了训练得到一个双向的表征,BERT简单的随机掩盖(mask)一些token,然后只预测被掩盖的词, 这个就被称为Masked LM。
因为下游的任务不会有[MASK]这个标识。所以这会在pre-training和fine-tuning之间存在mismatch,所以作者采用的mask策略是: 不是总用[MASK]替换掩盖的token,在训练数据中,随机选取15%的token进行预测,然后分别用80%[MASK],10%随机token,10%自己来替换第i个token。其他解释参考:appendix-A
然后使用交叉熵(cross entropy loss)使用最后一层的隐变量,来预测原始的token。这个任务的loss记作masked_lm_loss。
注意:masked_lm_loss只预测被mask的token,而不预测其他token。
- 2.2 Pre-training Task 2#: Next Sentence Prediction
因为很多下游的任务,比如QA,NLI都是需要学习sentence-level之间的关系。所以,BERT的另一而任务是进行一个二分类的下一个句子预测任务(Next Sentence Prediction,NSP)。 在构造训练数据时,50%的句子对{A,B}是IsNext关系,另外50%是NotNext关系。 这个任务的loss记作next_sentence_loss。
然后联合训练,最终的loss是两个任务loss的和: total_loss = masked_lm_loss + next_sentence_loss
- Fine-tuning
在预训练之后,模型的输出,token representation再经过一层网络进行token-level的任务,比如:实体标注,mrc等。头部的 [CLS] representation,用来进行分类任务,比如:情感分析,句子继承关系预测等。 当然,不同的任务需要自定义不同的loss函数,比如:
-
GLUE 使用开头的token[CLS],它的representaton记作, 分类那层的网络权重记作。然后使用一个标准的分类任务loss:。
-
SQuAD v1.1 构造输入A是question,B是passage。然后引入两个向量,开始位置向量和结束位置向量. 第i个word的representation记作,则它作为答案start下标的概率分布是: 答案的end下标概率分布使用相同的公式。 则候选答案span(从位置i到位置j)概率为:。最大得分的score并且同时满足,最为最终的预测结果。 训练目标是正确start和end的log-likelihoods和。
BERT适合的场景
- 解决句子或者段落的匹配类任务
- 在语言本身中就包含答案,而不特别依赖文本外的其它特征
- Bert比较适合解决输入长度不太长的NLP任务
- Bert的适用场景,与NLP任务对深层语义特征的需求程度有关。越是需要深层语义特征的任务,越适合利用Bert来解决
3. RoBERTa(2019.7.26)
RoBERTa(a Robustly Optimized BERT Pretraining Approach)是改进的BERT。这篇文章主要做的几点工作:
-
静态Masking vs 动态Masking
原来Bert对每一个序列随机选择15%的Tokens替换成[MASK],为了消除与下游任务的不匹配,还对这15%的Tokens进行(1)80%的时间替换成[MASK];(2)10%的时间不变;(3)10%的时间替换成其他词。但整个训练过程,这15%的Tokens一旦被选择就不再改变,也就是说从一开始随机选择了这15%的Tokens,之后的N个epoch里都不再改变了。这就叫做静态Masking。 而RoBERTa一开始把预训练的数据复制10份,每一份都随机选择15%的Tokens进行Masking,也就是说,同样的一句话有10种不同的mask方式。然后每份数据都训练N/10个epoch。这就相当于在这N个epoch的训练中,每个序列的被mask的tokens是会变化的。这就叫做动态Masking。 那么这样改变是否真的有效果?作者在只将静态Masking改成动态Masking,其他参数不变的情况下做了实验,动态Masking确实能提高性能。
-
with NSP vs without NSP
-
更大的mini-batch
-
更多的数据,更长时间的训练
4. AlBert (2019.12.26)
AlBert的主要探索在于如何减少参数、缩减模型,模型缩减了训练以及predict的时间都会减少,当然表现不能降低。 在一般的Bert网络中,令词典的embedding大小为,encoder layer为, 隐层大小为 , 然后设置feed-forward/filter size 为, attention的head数量为。 AlBert与Bert的模型主结构不变,主要进行了三点改进:
1.Factorized embedding parameterizatio
在Bert以及之后的一下改进工作,比如XLNet和RoBERTa中,WordPiece的词向量大小是与隐层大小有关联的,比如常等于。这种设置,也许不是必须的。作者认为,WordPiece的词向量是学习*语境独立(context-independent)的表征,而隐层向量是学习语境相关(context-dependent)*的表征。而Bert类模型的优势在于从语境中获取信号来学习与语境无关的表征,因此,将 WordPiece 词嵌入大小 从隐藏层大小分离出来,这样可以更高效地利用总体的模型参数, 其中远远大于。
如果字典大小是 ,那Bert类的模型的embedding矩阵大小是,这回轻松达到十亿级别的参数量。
所以,Albert想要打破 与 之间的绑定关系,从而减小模型的参数量,同时提升模型表现。
在AlBert中,对embedding的参数进行因式分解(factorization),将其分解为两个更小的矩阵。不是将one-hot的向量直接映射到大小的隐向量,在AlBert中,先将其映射到大小的embedding,然后再放进隐层。就是将embedding matrix分解为两个分别为和矩阵。这样就可以embedding向量从 变成 ,当远大于时,参数的减少是非常显著的。
上面图表示BERT的One-hot向量输入,第一次投影是词与词之间是没有交互的(context independent)。只有到了做Attention时,词与词之间才有交互(context dependent)。因此第一次投影不需要很高维度的向量。
而上图的AlBert中,可以把第一次的映射放到很低的维度,然后在context中做attention时,再放大到大维度。而NLP训练模型的vocab通常是很大的,所以第一次one-hot vector映射到embedding参数会很多。这样做有两个好处:
- 参数大大减小
- 词的Context independent表示与Context dependent表示之间解锁,可以自由的对Context dependent表示进行加高,也就是网络变宽
2.Cross-layer parameter sharing
有几种参数共享的方法可以选择,比如只共享层间前向网络的参数(feed-forward network,FFN),只共享attention的参数。而AlBert采用的策略是共享层间所有参数。
3.Inter-sentence coherence loss
Bert中使用两种loss,一个是masked_lm_loss,另一个是next_sentence_loss。有一篇文章讨论去掉next_sentence_loss,发现模型表现并没有太多影响。 所以作者猜想next_sentence_loss作用甚微的原因是,这个任务太过简单,模型只需要学习到两个句子主题不同就可以,且与MLM重复,导致Bert学习到的几乎都是来自MLM。所以,AlBert采用sentence-order prediction (SOP)loss,训练数据的构造与Bert相似,从同一篇文档中取出连续的两句话,作为正例子,相同的两句话调换顺序,作为负例。挺玄学的。
分析:
- 效果:AlBert比Bert只是在large以上的版本会比Bert好,比如 xlarge、xxlarge 。
- 速度:在predict阶段(前向传播),AlBert和Bert在同一版本几乎没有区别,严格来说,Albert还要更慢些,因为,AlBert的Embedding还要做一个矩阵分解的运算。所以,AlBert不能带来预测速度的提升!
5. ELECTRA (2020.4.23)
Bert使用的语言模型是MLM,即它随机mask 15%的token,然后训练模型来预测masked位置的token。而后Bert之大训练之难大家都知道,这篇ELECTRA借鉴了GAN的思路来搭建模型。Bert中是只预测被masked位置的token,这个任务太过简单(上一篇AlBert是觉得Next Sentence Prediction ,看来对Bert的改进就是让任务更难,必先苦其心志,劳其筋骨,饿其体肤,,)。那么如何引入一个更难的任务呢?它首先使用MLM模型,作者称为Generator,来改写一句话,就是对MASK位置替换成一些token,然后使用另一个网络,作者称为Discriminative,来预测句子中每个token是否被替换(序列标注问题)。 作者称这个任务叫做replaced token detection。
- Pre-training
模型结构如上图,Generator和Discriminator就是Bert编码器。在pre_training阶段,G和D一同训练,在fine_tuning阶段,G保持不变,只有D进行参数更新。
对于输入:,编码得到向量:
在pre_training阶段,因为无法在Generato和Discriminator中间进行back-propagate,所以实际上左右两个网络是独立训练的:
- Generator
左边的Generator网络,就是标准的MLM,在所有[MASK]位置计算预测token的概率,对于位置, Generator生成token 的概率是:
loss定义为:
- Discriminator
使用的训练sample,论文里称为corrupted example ,是使用Generator替换maskted-out的token生成的。
然后让Discriminator预测有没有被替换:
右边Disc的loss定义为:
- loss
最终的训练模式是将两个loss加权相加:
因为判别器的任务相对来说容易些,RTD loss相对MLM loss会很小,因此加上一个系数,作者训练时使用了50。
6. XLNet (2019.6.19)
作者将目前市面上的两种预训练模式定义为AR(autoregressive)和AE(autoencoding)。 AR模式有ELMO和GPT,它的问题是采用的单向的预言模型来预测,虽然ELMO使用两个方向的语言模型,但是效果还是很差。 AE模式,比如BERT,通过Masked LM可以很好的实现双向语言模型,但是存在两个问题:1. [MASK]字符只在pre-train中有,但是在fine-tuning中是不存在的,所以这造成了两个阶段的偏差。 2. BERT的假设是预测的tokens之间完全独立,这个与自然语言往往具有长依赖来说就太简单了。比如预训练时输入:“自然[Mask][Mask]处理”,目标函数其实是 ,而如果使用AR则应该是 。这样下来BERT得到的概率分布也是基于这个假设的,忽略了这些token之间的联系。
所以XLNet提出了方案,相比较BERT,有三点改动:
- 使用 Permutation Language Modeling。作者提出two-stream attention来实现。
- 借鉴Transformer-XL的思想,更适用于长文本,所以在SQuAD任务上表现更好。
- 不再使用NSP(Next Sentence Prediction)任务。XLNet采用Relative Segment Encoding,只判断两个token是否在一个segment中,而不是判断他们各自属于哪个segment。
- 更大更好的语料。
XLNet实现
- Permutations
对于序列 x = [This, is, a, sentence],序列长度是,则组合数量是个。比如,当给定前面两个,计算第三个位置token的概率时。假设有三个组合: [1, 2, 3, 4], [1, 2, 4, 3] 和 [4, 3, 2, 1] ,则它对应的概率就是:,和。
所以,XLNet的目标函数,就是在所有组合上进行AR预言模型,最大化单方向预测的组合似然概率:
- Attention Mask
模型解决token的order问题,在transformer中,是将position-embedding与word-embedding相加,同时作为输入。比如,。但是,在XLNet中,序列的次序是已经被打乱,所以使用这种相对位置就错误了。 这里使用attention mask来实现,比如对于组合[3,2,4,1],模型计算第一个位置,即'a',的概率,因为前面没有token,所以是没有语境,则它对应的掩码是[0,0,0,0]。 同理可以得到这个组合的掩码矩阵: 另一种表示是(表示这个位置是mask了):
- Two-stream self-attention
这是还需要考虑一个问题:我们不仅需要计算语境中预测某个位置token的条件概率,还需要知道模型正在预测的是哪个位置。也就是想计算:, this是,is是的概率。但是Transformer是直接把位置embedding与word embedding加到一起的,也就是:。但是在XLNet中,因为token顺序被打乱,所以模型不知道This是,甚至不知道This是不是在序列中。 解决方案是使用two-stream self-attention mechanism,在m层,每个位置的token,使用两个向量来表示:和。的初始化是word-embedding+position-embedding,而的初始化,是一般的embedding+position-embedding。是在content stream中更新,就是常规的self-attention,使用Q,K,V来更新。在query stream中更新,使用未mask部分的content vector作为K和V,上一层的它自己作为Q来更新。
下图展示了,在层,是如何更新的:
再会看论文中的例子和图: 对于一个输入序列(1,2,3,4),如果想要计算一个组合(3,2,4,1),通过掩码矩阵边可以实现,但实际上他的输入序列还是(1,2,3,4) 通过这个掩码计算的是:, , , ,也就是可以实现计算组合(3,2,4,1)。实际上就标准的self-attention。XLNet就是以这种方式,在构建预言模型的时候,同时“读到”后面的token。
图中掩码矩阵,红点表示不掩盖的部分。
参考1 Transformer 中self-attention以及mask操作的原理以及代码解析
7. SpanBERT (2019.7.24)
相比较Bert,SpanBERT的改变主要有两点:
- MLM,不在随机Mask,而是每次mask掉一个区间的所有token,而这个区间的长度和起始位置都是随机选择的。
- 不再使用NSP任务(Next Sentence Prediction ),代替使用SBO(Span Boundary Objective)任务。
上面图介绍了SpanBERT的训练模式。“an American football game”这个区间被mask掉,SBO使用区间两边token的隐层向量(, )来预测span中的每个token。上图就是在预测football时,MLM和SBO两个任务的loss说明,其中football是span中的第三个tokne,他的位置向量是。
1.mask span
对于一句输入,迭代构造mask输入,当mask的部分达到15%,结束这个过程。每次选择的span长度和span起始位置都是随机的,其中span长度服从几何分布,并且最大长度只能是 10。作者通过实验确定,当 p=0.2时表现最好,这时span的平均长度为3.8。
在Bert中,对于所有需要mask的token,会用[MASK]替换80%的词,10%的词随机替换成其他词,10%的词保持不变。在SpanBERT采用相同的策略,只不过它作用于每个span。
2.SBO task
当mask的span为,其中表示span的起始和结束位置,SBO任务就是用span两边token的representation (, ),来预测span中的每个token。当要预测位置的token的:
其中位置向量是相对于的相对位置, 就是使用一个简单的双层神经网络。
然后使用i位置的向量表示来预测,loss为计算交叉熵。
3.loss
前面连个任务的loss相加。
4.实施
- 位置向量使用200维的向量。
- 输入使用更长的sentence。
5.实验和分析
- SpanBERT 尤其在抽取式问答上表现好。
- 舍弃掉 NSP 的一段长句训练普遍要比原始 BERT 两段拼接的方式要好。
6.参考
8. Bert-WWM
Bert-WWM(Whole Word Masking)与Bert的区别,是在mask方式的区别。在英文语料中,句子的分隔使用WordPiece,就是将较长的单词分割,分别进行mask(在字典中使用“##token”来表示token是分隔的部分)。在中文Bert中,一般就直接在token_level进行 mask。而Bert-WWM是在将句子分词后,mask 某个token,同时mask这个token所在词语的其他token,模型输入还是在token级别。下面的例子更清楚:
| 说明 | 样例 |
|---|---|
| 原始文本 | 使用语言模型来预测下一个词的probability。 |
| 分词文本 | 使用 语言 模型 来 预测 下 一个 词 的 probability 。 |
| Bert的Mask结果 | 使 用 语 言 [MASK] 型 来 [MASK] 测 下 一 个 词 的 pro [MASK] ##lity 。 |
| Bert-WWM的Mask结果 | 使 用 语 言 [MASK] [MASK] 来 [MASK] [MASK] 下 一 个 词 的 [MASK] [MASK] [MASK] 。 |
然后其他方面与Bert都一样。
看一样他在LCQMC上的实验结果:
9. ERNIE (2019.3)
首先百度的RENIE与BERT的模型结构没有区别,区别在于它mask的词不是完全随机的,而是利用了图谱的知识。按照论文的说法,这样mask,ERNIE 直接对语义知识进行建模,增强了模型语义表示能力
-
不一样的mask方式
如图,bert只是mask单个token,而ERNIE采用了三种mask方式,分别是token,entity,phrase。
-
引入DLM学习对话
ERNIE 还引入了论坛对话类数据,利用 DLM(Dialogue Language Model)建模 Query-Response 对话结构,将对话 Pair 对作为输入,让模型来学习判断当前的多轮对话是真实的还是假的。。
10. ERNIE 2.0
引入多任务学习。 引入了多大7个任务来fine-tuning模型(不是在预训练阶段),并且采用的是逐次增加任务的方式来预训练