李宏毅老师2020新课深度学习与人类语言处理课程主页:
http://speech.ee.ntu.edu.tw/~tlkagk/courses_DLHLP20.html
视频链接地址:
https://www.bilibili.com/video/BV1RE411g7rQ
图片均截自课程PPT、且已得到李宏毅老师的许可:)
深度学习与人类语言处理 P18 系列文章目录
前言
上篇中(17-1,17-2,17精简)根据模型的输入输出进行了NLP的任务概述:文字->类别、文字->文字
而在本篇中,我们将讲解以 BERT 为代表的语言模型
本篇要讲机器怎么看懂人类的文字,或者换句话说,怎么让电脑看懂输入的文字,要讲的是这个方向上最新的技术,包括ELMO、BERT、GPT等
I Before BERT过去,在有ELMO、BERT之前,是怎么让电脑去读人类的文字的,如下图。
1.1 1-of-N Encoding
每一个词汇都当作一个不同的符号,最常见的做法就是1-of-N Encoding,如上图所示,把词表中的每一个词用一个独热编码表示。但这个方法显然是不足的,每一个词汇都用独热编码的话,对机器来说,每个词汇都是完全没有关系的,正如独热码的两两正交完全不相关。
也因此,产生了另一种方法,Word Class。
1.2 Word Class
Word Class是将词表中每个词分类,用这个类别表示其中的所有词汇,但这样太粗糙了,完全忽视掉了同一类中每个词的意义。
所以有了更进阶的想法,叫做 Word Embedding。
1.3 Word Embedding
Word Embedding 是指把每一个词汇都用高维向量表示,这个向量的每一个维度可能就表示了这个词汇某些方面的意思。这样语义相近的词汇,其向量也更加接近,如上图所示,run和jump都是动词,它们的高维向量经过降维后显然更接近。
但是这样做也有一个问题,那就是同一个词汇,无论上下文如何变化,其表示都是固定的,无法表达词汇的多义性。
那该怎么表示同一个词汇在不同语境下的不同意思呢?
1.4 Contextualized Word Embedding
Contextualized Word Embedding 可以解决上述多义问题,它可看作 Word Embedding + 上下文。
这种模型可以给不同语境(即不同上下文)的同一词汇 不同的向量表示,那该如何实现这种可以结合上下文的词向量表示法呢?著名的ELMO就是经典的表示上下文词向量的模型。
Embeddings from Language Model
2.1 RNN-based language model
ELMO是一个RNN-based language model,这种RNN-based的语言模型不需要任何有标注的训练资料,只需要大量的普通文章即可,它的训练目标就是根据已有的上文预测输出下一个token,如上图左侧所示,若训练资料是 “潮水 退了 就 知道 谁 没穿 裤子”,则模型需要根据<BOS>预测潮水,<BOS>+潮水预测退了,<BOS>+潮水+就预测谁,以此类推。最终预测结束后,将RNN的隐藏层作为对应输入词的词向量表示。
如果仅仅这样做,会有这样的不足,每一个词的词向量仅考虑了上文,而忽略了后文的影响。因此,ELMO中 又加了上图右侧的反向RNN来同样生成词向量,此时模型需要根据 <EOS>预测裤子, <EOS>+裤子预测没穿,<EOS>+裤子+没穿预测谁,以此类推。同样,将RNN隐藏层作为对应输入词的词向量表示。
2.2 Deep and Bi-directional RNN
同样,深度神经网络的深在此体现,不仅仅使用一层RNN,而是很多层RNN,那此时,一个词汇将会由多层RNN中每一层的正向RNN和反向RNN各得到一个词向量,那一个词汇改选用哪个向量作为词向量呢?
2.3 Weighted Embedding
在原始的ELMO论文中,方法就是我全都要!!,将每层的向量加权相加得到最终的词向量,如上图所示的 α 1 和 α 2 \alpha_1和\alpha_2 α1和α2就是 h 1 和 h 2 h_1和h_2 h1和h2的权重参数,其中这个权重参数是跟着down-stream任务一起训练得到的。
在实验中表明,对于不同任务,模型的不同层提取到的信息是不同的,如上图右侧,Coref和SQuAD任务,在LSTM第一层的信息是其词向量很重要的组成向量。
III BERTBidirectional Encoder Representations from Transformers
3.1 Overview of BERT
正如上图所写,BERT就是Transformer模型的Encoder部分,上图右下的结构图就是Transformer模型的结构图,其中框住的Encoder部分其实就是BERT的简易结构图,只不过BERT的模型层数更多。
同样,BERT也是只需要普通的语料即可训练,不需要有标记的数据、不需要具体的任务来训练。
简要而言,
BERT实际上就是在给一个句子进去,每一个句子都会吐一串Embedding给你,每个Embedding就对应到一个token,就结束了。
那至于BERT里面的架构具体是什么样子呢?就和Transformer模型的Encoder是一样的,那这个Encoder里都有什么呢?有self-atttention层。
注意,上图的例子给的是以中文词汇为token的处理,但其实更多时候我们会直接以字为token进行模型训练与down-stream任务。因为中文的词汇量太大了,但常用字是有限的。
那对于没有标签的数据,BERT该怎么进行训练呢?
3.2 Training of BERT
在文献上,BERT这个模型有两个训练的方式:
- Masked LM
- Next Sentence Prediction
3.2.1 Masked LM
第一个方法, Masked LM 的意思是说,我们把输给BERT的词汇有15%的进行 [MASK] 替换。而BERT要做的就是根据每一句中剩余未MASK掉的词汇去预测MASK的词汇是什么,具体而言,如上图,输入的词汇经过BERT编码后变成一串向量,这其中被MASK的词汇的向量将丢给一个线性多分类模型中去预测应该是词表的哪个词。因为这个分类模型是个线性分类器,能力很弱,所以如果这种分类器都能根据BERT编码后的句子去预测得到MASK的内容说明BERT的编码很 “理解语言”。
也因此,如果两个词汇填在同一个地方没有违和感,那么它们就有类似的embedding,也有类似的语义。
3.2.2 Next Sentence Prediction
第二种方法,Next Sentence Prediction,要求BERT判断输入两个句子是不是语义上相接的。举例来说,给BERT两个句子“醒醒吧”和“你没有妹妹”,这两个句子是可以接在一起的,因此我们也希望BERT模型能够根据这两个输入输出能相接。但在输入两个句子中间,我们加了特殊的token“[SEP]”表示句子间的交界,同时在句子开头加了“[CLS]”代表我们要做分类这件事,从这个“[CLS]”输入的位置对应的输出的embedding,丢给线性分类器里要它输出是否应该被接在一起。
这时,可能会有人问,为什么不把[CLS]放在句子的结尾呢?放在结尾不是可以让BERT读完整个输入部分的两个句子,之后再做分类的词向量表示更好么?但是仔细想BERT的模型结构就解决了这个疑问,如果BERT里面用的是RNN,那[CLS]确实放在句尾更合理。但BERT内部并不是RNN,是一个Transformer的Encoder,是一个self-attention,而对于self-attetion而言,假如不考虑positional encoding所造成的影响,一个输入部分的token无论放在哪里都一样,所以[CLS]的位置对BERT是没有差别的。
以及这个 Linear Binary Classifier和BERT是一起训练的。
至此,我们有了两种训练BERT的方法,我们该选哪一种,文献写到这两种方法同时训练效果最佳。
注:以上虽然以词汇为例子,但是记得对于中文NLP任务使用字的效果更好更实用。
那BERT训练好了之后,我们该怎么用BERT呢?
3.3 Use BERT
简单点的使用方法是,将BERT看作更强大的Embedding词向量编码器,将所有的词汇编码成词向量来使用。
但BERT论文中,它不是只有做这样的事情,它说它是把BERT与down-stream任务进行一起训练的,也就是说将BERT与down-stream任务的模型组合到一起。那我们该怎么把BERT和具体任务结合在一起进行训练呢?
3.3.1 Case 1 Output class of one sentence
输入:sentence
输出:class
第一个例子是分类任务,如情感分析、文章分类,那我们怎么使用BERT呢?
解法:就是把要分类的句子丢给BERT,但开头要加代表分类的符号”[CLS]“,如上图,接下来把[CLS]对应位置的embedding丢给一个线性分类器里,这个分类器去预测这个句子是哪个类别。
此时,这个Linear Classifier线性分类器是从头开始训练的,但BERT是可以Fine-tune微调的,当然BERT也可以从头学,但这样BERT参数过多,训练时间会非常久。
3.3.2 Case 2 Output class for each token
输入:sentence
输出:class for each token
第二个例子是token标注,如slot-filling、词性标注,要给输入的句子里的每一个token都输出一个类别。那该怎么用BERT解这样的问题呢?
解法:对于输入的句子,BERT编码后会得到句中每一个token的embedding,再将这些embedding丢给线性分类器中,进行分类任务。
同样,训练的时候,分类器和BERT一起训练,只不过BERT微调即可。
3.3.3 Case 3 Output class of two sentences
输入:two sentences
输出:class
第三个例子是两个句子的关系分类任务,如NLI自然语言推理、相似句判断,要给输入的两个句子预测一个类别的任务。
解法:同样,将这两个句子中间加"[SEP]",开头加“[CLS]”再丢给BERT,将"[CLS]"对应位置输出的embedding给线性分类器中进行分类任务。
3.3.3 Case 4 QA
输入:document + question
输出:two numbers
第四个例子是解QA问题,而且是Extraction-based Question Answering,如SQuAD,给模型读一篇文章,并提出一个问题,希望模型能正确的得到答案,且答案是原文中的一部分。
将文章和问题都用token sequence来表示,对于QA问题,如上图,将D、Q都输入给模型中输出s和e,答案就是文章中索引从s到e的所有token。那怎么用BERT来解这个QA问题呢?
解法:将问题和文章中间加"[SEP]",开头加"[CLS]"输入给BERT,此时我们得到了每一个对应位置的embedding,另外,再从头训练两个向量 橙蓝,其维度和 黄色embedding是一样的,然后将橙色的向量与文章的embedding做dot-product点积运算得到每一个文章内的词汇的scalar,再将其softmax后得到对应分数,找出其中分数最高的,如上图的d2,此时s就等于2。同理,蓝色的向量与橙色的向量运算过程一样,得到e等于多少。至此,答案就是 “ d s 至 d e ” “d_s至d_e” “ds至de”。
在训练的时候,橙蓝向量从头训练,BERT微调就好。
此时,会有这样的问题,假设s和e矛盾了,比如s=3,e=2,这不是没有答案了吗?对,此时模型就是输出此题无解,在SQuAD2.0中是有无解的问题的。
至此,就是BERT的四种用法。
3.4 Result
之后,BERT就是到处屠榜,很多的经典NLP任务,如SQuAD2.0,排行榜第一名BERT做的,第二名也是用BERT做的,第三名也是BERT做的…
3.5 BERT layer
既然BERT有那么多层,那每一层到底都学到了什么呢?BERT的每一层做的像是NLP各个任务的pipeline,且层由浅入深其代表的NLP任务越来越复杂。
举例来说,如上图BERT有24层,所以每个词汇有24个vector,把这些vector乘上对应的权重参数加权求和得到最终词汇的embedding。上图右侧就是把BERT的每一层的权重参数提取出来,深蓝色的方块就是权重参数。可以看到对于POS词性标注任务,第10-12层的权重参数更大,表示这几层对于POS来说是更重要的。而困难一些的NLP任务可以看到后面几层的权重参数更大,这也就体现了BERT对于语言模型的理解能力,由浅入深,由简至难。
3.6 Multilingual BERT
Multilingual BERT是谷歌通过爬去104种语言的*资料训练得到的多语种BERT,神奇的是,在将这个多语种BERT训练学会英文的文本分类任务后,它竟然可以做出其他语言的文本分类,如中文的文本分类,它看过中文,但从来没有人教他中文文本该怎么分类,但学会英文分类后就自动学会了中文分类。
Enhanced Representation through Knowledge Integration
继BERT之后,又有了ERNIE,它是特别为了中文所设计的。简单来讲,它的概念就是对于BERT而言,要做MASK LM,MASK的是随机的token,而中文如果仅仅MASK随机的字,模型是很容易猜出来的其训练效果一般。因此MASK采取的是MASK掉整个词汇,按词随机MASK。“细节请大家再看一下文献”。
5.1 Introduction
接下来,我们将进入另外一个“伟大”的模型,GPT(1和2),它其实就是一个硕大无穷的语言模型。它的魅力就是“大”!
但GPT其实就是Transformer的Decoder部分(注意BERT就是Transformer的Encoder),那GPT是怎么运作的呢?
5.2 self-attention in GPT
简要而言,GPT要做的事请和一般的语言模型是一样,给它一些词汇,预测下一个词汇应该是什么。举例来说,如上图,给GPT<BOS> 和 潮水,希望它可以预测 “退了”这个词汇,那它怎么输出 “退了”这个词汇呢?一样,它也要对已输入的token做self-attention。如上图,在预测“退了”这个词汇时,要将潮水的 q 2 q_2 q2(Query)分别与 k 1 , k 2 k_1,k_2 k1,k2(Key)做点积后分别得到 α 2 , 1 和 α 2 , 2 \alpha_{2,1}和\alpha_{2,2} α2,1和α2,2,再将其分别乘以 v 1 , v 2 v_1,v_2 v1,v2(Value)并加权求和得到 b 2 b_2 b2,再将这个vector经过很多层并做分类任务预测得到“退了”这个词汇,预测“退了”这个词汇后再把它拿下来放到输入部分,依次预测。
5.3 Zero-shot Learning
GPT-2非常巨大,所以它就展现了种种的神机,在我看来,GPT-2做到了很多神奇的事请。
GPT-2可以在完全没有对应训练资料的情况下,就做到Reading Comprehension、Summarization和Translation,可以做到Zero-shot Learning 零样本学习。
一般来说,对于这些任务,是需要对应有标注的训练资料的,即使是BERT也需要对应的训练资料。但GPT-2尝试在完全没有QA训练资料的情况下就可以做QA任务,怎么做呢?直接给GPT-2一篇文章,再给出问题,接下来再输入"A:",它就会输出答案。
摘要也是,输入一篇文章,接下来输入一个特殊的符号,“TL;DR:”,接下来GPT-2就自动输出这篇文章的摘要。
对于Translation翻译任务,同样,输入几段英文句子=中文句子后,再输入给GPT-2具体的翻译任务,”英文句子3 = “,GPT-2就会输出翻译后的中文句子。
本篇内容顺序结构与老师不同,但内容不变不缺,都是为了大家方便学习理解。
至此,经典”伟大“的语言模型概述完成。