ELMO,BERT,GPT
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
词向量在语言处理中有重要角色,它将抽象的词语之间的语义关系量化成向量形式,有了良好的词向量,我们可以做更多工作,目前构建词向量主要分两大类:
统计方法:通过统计词语之间的关系,从构建词向量,定义一些显性隐性的关系。例如SVD, LSA
等,这样做法在逻辑上不是特别理性,效果上也不好。
语言模型:通过构建语言模型来实现对词向量的学习,在理论上可行,并且目前大部分工作都是基于这样的思想,从最开始的神经网络语言模型(NNLM)到后来的Word2vec、GloVe等。
基于双向的LSTM拼接
与之前工作不同的是,该模型不仅去学习单词特征,还有句法特征和语义特征,后两者的特征是来自LSTM的隐含输出向量,此处的模型目标是预测对应位置的下一个单词(也就是T1的向量应该预测输出E2的单词)。
EMLO(Embedding from Language Model)的缩写,它是一个RNN-based
的模型,只要有大量句子就可以训练,ELMO的作用是训练一个模型,用来表示某个词,换句话说,和Word2vec和GloVe是一样的,它有两个步骤:
能够处理单词用法中的复杂特性(句法和语义)
有些用法在不同的语言上下文中如何变化(比如为词的多义性建模)
我们可以把训练的RNN隐藏层权重拿出来,把词汇经过隐藏层后输出的向量当做这个单词的Embedding,因为RNN是考虑上下文的,所以同一个单词在不同的上下文中它会得到不同的向量,上图是一个正向里的RNN,如果觉得考虑信息不够,可以训练双向RNN,同样将隐藏层的输出作为embedding
。
如果RNN有很多层,实际操作过程中要拿哪一层的输出作为embedding
:
在ELMO中,它取出每一层得到的向量,经过运算得到我们每一个单词的embedding
:
如上图,假设有2层,所以每个单词都会得到2个向量,最简单的方法就是把向量加起来作为这个单词的embedding
,EMLO中会把两个向量取出来,然后乘以不同的权重,再将得到的我们得到的embedding
做下游任务。也是模型学习得到的,它根据我们的下游任务一起训练得到,所以不同任务用到的是不一样的:
如上述的embedding
可以有三个来源:
原来没有经过contextualized
的embedding
,上图中的Token
。
Token
经过第一层抽象出第一个embedding
。
Token
经过第二层抽象出第二个embedding
。
基于单向的Transformer模型
GPT(Generative Pre-Training),Transformer作为RNN的替代结构,构建了新的模型,模型的任务有txtpredication
和task classifier
,需要注意的是GPT中的Transformer中只有Decode
部分:
根据上图可得到预训练的模型,然后在这样的模型上再次接上下游任务,与ELMO只提供向量不同,这里预训练的模型一同提供给下游的任务,这里的模型的向量是可以随着新的下游任务发生微小的调整,也就是Fine-Tune
:
基于双向的Transformer模型
BERT(Bidirectional Encoder Representations from Transformers),BERT实际上也使用了Transformer的Encoder作为编码器,使用大量文本进行预训练;不同的NLP任务通常需要不同的模型,而设计这些模型并测试Performance非常耗成本,如果有一个能直接处理各式NLP任务的通用架构该有多好?
漏字填空(完型填空),学术点的说法是Masked Language Model
判断第二个句子在原始本文中是否跟第一个句子相接(Next Sentence Prediction)
在BERT中,Masked LM(Masked Language Model)构建了语言模型,简单说就是随机遮盖或替换一句话里面的任意字或词,然后让模型通过上下文预测哪一个被遮盖或替换的部分,之后做Loss的时候也只计算被遮盖部分的Loss,这其实是一个很容易理解的任务:
随机把一句话中15%的Token(字、词)替换成下边内容:
这些Token有80%的几率被替换成[MASK]
有10%的几率被替换成任意一个其他的Token
有10%的几率原封不动
之后让模型预测和还原被遮盖掉或替换掉的部分,计算损失的时候,只计算在第一步里被随机遮盖或替换的部分,其余部分不做损失,其余部分无论输出什么东西,都无所谓
我们首先拿到属于上下文的一对句子,也就是两个句子,之后我们要在这两个句子中加一些特殊的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相加。
如果现在任务是classification,首先在输入句子的开头加一个代表分类的符号[CLS]
,然后将该位置的输出,丢给线性分类器Linear Classifier,让其预测一个类即可。整个过程中的线性分类器的参数是要从头开始学习的,而BERT中的参数微调就可以了。
如果现在任务是Slot Filling,将句子中各个字对应位置的输出分别送入不同的Linear
,预测出该字的标签——其实本质上海市分类问题,只是每个字都要预测一个类别。
如果现在任务是NLI(自然语言推理),即给定一个前提,然后给出一个假设,模型要判断出这个假设是正确、错误还是不知道,本质上是一个三分类的问题,和Case 1
差不多,对[CLS]
的输出进行预测即可。
如果现在的任务是QA(问答),将一篇文章、问题送入模型,会得到两个数的s,e
,这两个数表示:这个问题的答案落在文章的第s
个词到第e
个词,其流程如下:
首先将问题和文章通过[SEP]
分割,送入BERT之后,上图中的黄色输出,此时还要训练两个Vector,即上图中橙色和黄色的向量。
首先将橙色和所有的黄色向量进行点乘,Dot Product
之后通过看哪一个输出的值最大
【参考:)】
【参考:)】
Fine-Tuning,BERT的Fine-Tuning总共分四种类型,参考(李宏毅课程)。