ELMO,BERT,GPT

    词向量在语言处理中有重要角色,它将抽象的词语之间的语义关系量化成向量形式,有了良好的词向量,我们可以做更多工作,目前构建词向量主要分两大类:

  • 统计方法:通过统计词语之间的关系,从构建词向量,定义一些显性隐性的关系。例如SVD, LSA等,这样做法在逻辑上不是特别理性,效果上也不好。

  • 语言模型:通过构建语言模型来实现对词向量的学习,在理论上可行,并且目前大部分工作都是基于这样的思想,从最开始的神经网络语言模型(NNLM)到后来的Word2vec、GloVe等。

1. ELMO

基于双向的LSTM拼接

    与之前工作不同的是,该模型不仅去学习单词特征,还有句法特征和语义特征,后两者的特征是来自LSTM的隐含输出向量,此处的模型目标是预测对应位置的下一个单词(也就是T1的向量应该预测输出E2的单词)。

    EMLO(Embedding from Language Model)的缩写,它是一个RNN-based的模型,只要有大量句子就可以训练,ELMO的作用是训练一个模型,用来表示某个词,换句话说,和Word2vec和GloVe是一样的,它有两个步骤:

  1. 能够处理单词用法中的复杂特性(句法和语义)

  2. 有些用法在不同的语言上下文中如何变化(比如为词的多义性建模)

【参考:https://www.cnblogs.com/dogecheng/p/11615750.htmlarrow-up-right)】

    我们可以把训练的RNN隐藏层权重拿出来,把词汇经过隐藏层后输出的向量当做这个单词的Embedding,因为RNN是考虑上下文的,所以同一个单词在不同的上下文中它会得到不同的向量,上图是一个正向里的RNN,如果觉得考虑信息不够,可以训练双向RNN,同样将隐藏层的输出作为embedding

    如果RNN有很多层,实际操作过程中要拿哪一层的输出作为embedding

    在ELMO中,它取出每一层得到的向量,经过运算得到我们每一个单词的embedding

    如上图,假设有2层,所以每个单词都会得到2个向量,最简单的方法就是把向量加起来作为这个单词的embedding,EMLO中会把两个向量取出来,然后乘以不同的权重α\alpha,再将得到的我们得到的embedding做下游任务。α\alpha也是模型学习得到的,它根据我们的下游任务一起训练得到,所以不同任务用到的α\alpha是不一样的:

    如上述的embedding可以有三个来源:

  • 原来没有经过contextualizedembedding,上图中的Token

  • Token经过第一层抽象出第一个embedding

  • Token经过第二层抽象出第二个embedding

2. GPT

基于单向的Transformer模型

    GPT(Generative Pre-Training),Transformer作为RNN的替代结构,构建了新的模型,模型的任务有txtpredicationtask classifier,需要注意的是GPT中的Transformer中只有Decode部分:

    根据上图可得到预训练的模型,然后在这样的模型上再次接上下游任务,与ELMO只提供向量不同,这里预训练的模型一同提供给下游的任务,这里的模型的向量是可以随着新的下游任务发生微小的调整,也就是Fine-Tune

3. BERT

基于双向的Transformer模型

    BERT(Bidirectional Encoder Representations from Transformers),BERT实际上也使用了Transformer的Encoder作为编码器,使用大量文本进行预训练;不同的NLP任务通常需要不同的模型,而设计这些模型并测试Performance非常耗成本,如果有一个能直接处理各式NLP任务的通用架构该有多好

【参考:https://blog.csdn.net/qq_37236745/article/details/108845397arrow-up-right)】

  1. 漏字填空(完型填空),学术点的说法是Masked Language Model

  2. 判断第二个句子在原始本文中是否跟第一个句子相接(Next Sentence Prediction

3.1.Masked Language Model

    在BERT中,Masked LM(Masked Language Model)构建了语言模型,简单说就是随机遮盖或替换一句话里面的任意字或词,然后让模型通过上下文预测哪一个被遮盖或替换的部分,之后做Loss的时候也只计算被遮盖部分的Loss,这其实是一个很容易理解的任务:

  1. 随机把一句话中15%的Token(字、词)替换成下边内容:

    1. 这些Token有80%的几率被替换成[MASK]

    2. 有10%的几率被替换成任意一个其他的Token

    3. 有10%的几率原封不动

  2. 之后让模型预测和还原被遮盖掉或替换掉的部分,计算损失的时候,只计算在第一步里被随机遮盖或替换的部分,其余部分不做损失,其余部分无论输出什么东西,都无所谓

3.2.Next Sentence Prediction

    我们首先拿到属于上下文的一对句子,也就是两个句子,之后我们要在这两个句子中加一些特殊的Token:[CLS]上一句话[SEP]下一句话[SEP],也就是在句子开头加一个[CLS],在两句话之间和句末加[SEP],具体图示如:

    从上图可以看到两句话明显是连续的,如果现有一句话[CLS]我的狗很可爱[SEP]企鹅不擅长飞行[SEP],可见这两句话就不是连续的,而实际训练中这两种情况出现的数量为1:1

  • Token Embedding就是正常的词向量

  • Segment Embedding的作用是embedding的信息让模型分开上下句,此处给上句的Token全0,下句的Token全1,让模型得以判断上下句的起止位置

  • Position Embedding和Transformer中的不一样,不是三角函数,而是学习出来的

    Multi-Task Learning,BERT预训练阶段实际上是将上述两个任务结合起来,同时进行,然后将所有的Loss相加。

    Fine-Tuning,BERT的Fine-Tuning总共分四种类型,参考Machine Learningarrow-up-right(李宏毅课程)。

3.2.1.Case 1

    如果现在任务是classification,首先在输入句子的开头加一个代表分类的符号[CLS],然后将该位置的输出,丢给线性分类器Linear Classifier,让其预测一个类即可。整个过程中的线性分类器的参数是要从头开始学习的,而BERT中的参数微调就可以了。

3.2.2.Case 2

    如果现在任务是Slot Filling,将句子中各个字对应位置的输出分别送入不同的Linear,预测出该字的标签——其实本质上海市分类问题,只是每个字都要预测一个类别。

3.2.3.Case 3

    如果现在任务是NLI(自然语言推理),即给定一个前提,然后给出一个假设,模型要判断出这个假设是正确、错误还是不知道,本质上是一个三分类的问题,和Case 1差不多,对[CLS]的输出进行预测即可。

3.2.4.Case 4

    如果现在的任务是QA(问答),将一篇文章、问题送入模型,会得到两个数的s,e,这两个数表示:这个问题的答案落在文章的第s个词到第e个词,其流程如下:

    首先将问题和文章通过[SEP]分割,送入BERT之后,上图中的黄色输出,此时还要训练两个Vector,即上图中橙色和黄色的向量。

  1. 首先将橙色和所有的黄色向量进行点乘\odot,Dot Product

  2. 之后通过SoftmaxSoftmax看哪一个输出的值最大

最后更新于