论文来源:NAACL 2019
论文链接:点击进入
文章目录
🚀该论文提出了一个新的语言表示模型:BERT。其设计的目的是通过联合调节所有层的左右上下文,来预训练未标记文本的深度双向表示(使用transformer作为算法的主要框架)。可以通过在预训练的BERT模型后加上额外的层来微调,以实现不同任务的需要(如文本分类,NER等)。BERT在11项nlp任务中达到了SOTA。
【注:Bert使用了Mask Language Model(MLM) 和 Next Sentence Prediction(NSP) 的多任务来预训练,这些数据都是不用人工标注的,如MLM中随机挖空,将挖空的单词作为预测目标。
所以,BERT的本质上是通过在海量的语料的基础上运行自监督学习方法为单词学习一个好的特征表示,所谓自监督学习是指在没有人工标注的数据上运行的监督学习。
也就是说,BERT提供的是一个供其它任务迁移学习的模型,该模型可以根据任务微调或者固定之后作为特征提取器】
⭐介绍&动机:
有2中策略来应用预训练模型:
1.基于特征:将预训练的表示作为额外特征引入具体任务。
2.基于微调:引入少量任务特征参数,在下游任务训练时微调这些参数。
作者怀疑现有的方式限制了预训练表示的能力,尤其是微调的方式。最主要的缺点是标准的语言模型不是双向的,而双向的上下文对于句子级别任务而言十分重要。
BERT通过引入一个新的预训练任务 “Masked Language Model” (MLM)来解决非双向的限制。通过从输入中随机的遮盖(masked)一些词汇,基于剩下的词汇将抹掉的词汇作为预测的标签,和左到右单向的预训练语言模型不同,MLM允许混合左和右的上下文来表示,让我们可以预训练一个深度的双向Transformer,除此之外,我们额外添加一个任务Next Sentence Prediction(NSP) ,预测两个句子是否是相邻关系,一起参加预训练。
【注:这里的双向不是bi-lstm里的双向,而是得益于transformer里的self-attention层,每个单词会注意到所有的单词,就比如在这个MLM任务中,模型会根据挖空的上下文来进行预测,这就实现了双向表示,所以bert是双向语言模型。而OpenAI-GPT模型也用了transformer,但是其用的是decoder中,去掉了encoder-decoder attention层的masked self-attention层,其每个单词只与前面的单词相关,所以其是单向语言模型。】
⭐BERT的网络结构:
其实就是多个transformer的encoder结构的堆叠,decoder层如下:
【注:transformer原理可以看这:《Attention Is All You Need》论文笔记 - 【transformer模型】】
BERT提供了简单和复杂两个模型,对应的超参数分别如下:
BERT_BASE: L=12,H=768,A=12,参数总量110M;
BERT_LARGE : L=24,H=1024,A=16,参数总量340M;
L:网络层数(即transformer中的decoder的数量)
A:多头注意力中self-attention的数量
H:隐藏层大小(In all cases we set the feed-forward/filter size to be 4H, i.e., 3072 for the H = 768 and 4096 for the H = 1024.#pic_center)
⭐BERT的输入表示:
为了能够处理多种下游任务,BERT的输入表示可以是单个句子的,也可以是句子对(如<question, answer>)的一个token序列。
BERT的输入的编码向量(长度是512)是3个嵌入特征的之和,如下图:
这三个词嵌入特征是:
1.token embedding用的是WordPiece嵌入:字面理解是把word拆成piece一片一片。WordPiece的一种主要的实现方式叫做BPE(Byte-Pair Encoding)双字节编码。比如"play",“played”,“playing"这三个单词等,可能会有很多不同后缀,会使词表很大,不利于训练。而BPE算法通过训练,能过将其拆分成"play”,“ed”,"ing"几部分,这样可以把词的本身的意思和时态分开,有效的减少了词表的数量。
每个序列的开始时一个用于分类的嵌入(表示该特征用于分类模型):[CLS],而对于非分类任务可以省去。
2.segment embedding:作者用两种方式区分两个句子。第一:例如一个句子对,用 [SEP] 分割开,如图像,如图EA是句子A的嵌入,EB是句子B的嵌入。而对于单句的话,只用EA。第二:就是segment embedding了。例如两组向量:[ [0,0,…], [1,1,…] ]区分两句话。
3.position embedding:即位置编码。
从下面图中最后一层可以看到,每个token都对应一个学习到的隐层向量。[CLS]对应最后一层隐层状态C(其用于分类任务的聚合序列表示),其它的token对应T_i,最后一层的输出即各token经过BERT处理后得到的特征向量。
例如下面的C作为NSP的预测,其他两个mask的地方对应的输出隐层向量作为MLM任务的预测。
⭐预训练任务:
BERT是一个多任务模型,它的任务由两个自监督任务组成:MLM、NSP。
1.MLM(Masked Language Model):
所谓MLM是指在训练的时候随即从输入预料上mask掉一些单词,然后通过的上下文预测该单词。
在BERT的实验中,15%的WordPiece Token会被随机Mask掉。在训练模型时,一个句子会被多次喂到模型中用于参数学习,但是Google并没有在每次都mask掉这些单词,而是在确定要Mask掉15%的单词之后:
- 80%的时候会直接替换为[Mask]。 为了让模型学习到双向的上下文信息,但由于mask位置是看不到的,导致模型看不到本身被mask的token的信息,但finetune确实可以看到当前token,这就造成了模型没有学会根据上下位词的表示来调整当前词的表示的能力。所以self-attention参数更新过程中,会弱化[MASK]自身对生成向量的影响,尽量用周边向量生成[MASK]位置对应的向量。这样虽然学习到了上下文的信息,但是带来了一个问题:因为[MASK]的信息在生成向量中没有贡献,那么模型仅关心周边的信息。采用80%的概率下应用[MASK], 既可以让模型去学着预测这些单词, 又以20%的概率保留了语义信息展示给模型。
- 10%的时候将其替换为其它任意单词。 这样模型并不知道该位置是mask还是原词还是随机的词,就迫使模型结合上下文去预测纠正该位置的token。此外15%*10%=1.5%的随机替换,这个量不大,并不会影响对原有句子的理解。
- 10%的时候会保留原始Token。 虽然保留,但是也要预测出来。意义就是保留语言本来的面貌, 让信息不至于完全被遮掩, 使得模型可以"看清"真实的语言面貌。
另外文章指出每次只预测15%的单词,因此模型收敛的比较慢。
2.NSP(Next Sentence Prediction):
NSP的任务是判断句子B是否是句子A的下文。如果是的话输出’IsNext‘,否则输出’NotNext‘。训练数据的生成方式是从平行语料中随机抽取的连续两句话,其中50%保留抽取的两句话,它们符合IsNext关系,另外50%的第二句话是随机从预料中提取的,它们的关系是NotNext的。这个关系保存在图4中的[CLS]这个token对应的最后输出的隐层向量中,如上图的C。
⭐微调:
在海量数据上预训练完BERT后,就可以将其应用到各NLP任务中了。对应NSP任务,利用输出的C传入个全连接层即可判断句子B是否是句子A的下文,像下面这样:
对于其他任务,即将token对应的最后输出的隐层向量,用于各种任务(如NER,问答任务等),如下图为BERT用于11个不同任务的模型,即在BERT的基础上再添加一个输出层即可完成特定任务的微调。:
对于模型参数的调整、微调策略、模型性能对比、消融实验具体参见论文。
⭐总结:
最近的迁移学习的经验改进已经证明了,丰富的,无监督的预训练是许多语言理解系统不可或缺的一部分。BERT的成功也表明了迁移学习的一次胜利。
~~突然觉得BERT能干很多事情,一个字:牛!