目录
摘要
1.引言
2.相关工作
2.1Feature-based Approaches
2.2Fine-tuning方法
3 BERT
3.1 Model Architecture
3.2 Input Representation
3.3 Pre-training Tasks
3.3.1 Task #1: Masked LM
3.3.2 Task #2: Next Sentence Prediction
3.4 Pre-training Procedure
3.5 Fine-tuning Procedure
4 Experiments
4.1 GLUE Datasets(The General Language Understanding Evaluation benchmark)
4.1.1 GLUE Results
4.2 SQuAD v1.1
4.3 Named Entity Recognition
4.4 SWAG
5 Ablation Studies
5.1 Effect of Pre-training Tasks
5.2 Effect of Model Size
5.3 Effect of Number of Training Steps
5.4 Feature-based Approach with BERT
谷歌提出的BERT模型是建立在transformer的基础上,采用双向的transformer,以此建立一个通用的NLP模型,对于特定任务只需要加一个额外的神经网络层即可,相当于把下游任务的工作转移到预训练阶段,BERT模型在11个NLP任务上都有非常优异的表现,并在某些方面的性能超过了人类表现。
语言模型的预训练已经在很多任务上被证明具有很大的作用,比如句子级的自然语言推断,token级的命名实体识别,SQuAD的问答系统等,针对下游任务的预训练方法主要有两种:feature-based and fine-tuning。
在以前的工作中这两种预训练方法都是采用相同的损失函数,并且他们使用的都是单向的语言模型。正是由于单向的语言模型的限制,使得现在的预训练方法,特别是fine-tuning方法很难发挥最大的作用。比如在OpenAI GPT中,由于采用单向的语言模型,每一个token只能从其左边的token接受信息。这样的限制对采用fine-tuning方法的token任务是灾难性的(相当于做完形填空不能从下文获得信息)。
因此在这篇论文中提出了基于fine-tuning这种预训练方法的BERT,通过“masked language model”解决上文提出的单向语言模型的限制,MLM方法将要预测的词用mask表示,以此来实现同时训练左边和右边上下文的深层的transformer。除了MLM,本论文还采用“next sentence prediction”联合进行预训练。
这篇文章的贡献点如下:
1.证明了双向预训练模型的重要性
2.预训练可以消除特定任务繁重的工程性工作,BERT在句子级和token级都取得了优异的表现
3.该文章同时做了大量消融实验证明每一部分的贡献
Feature-based指利用语言模型的中间结果也就是LM embedding, 将其作为额外的特征,引入到原任务的模型中,例如在TagLM[1]中,采用了两个单向RNN构成的语言模型,将语言模型的中间结果
引入到序列标注模型中,如下图所示,其中左边部分为序列标注模型,也就是task-specific model,每个任务可能不同,右边是前向LM(Left-to-right)和后向LM(Right-To-Left), 两个LM的结果进行了合并,并将LM embedding与词向量、第一层RNN输出、第二层RNN输出进行了concat操作。
TagLM模型示意图
通常feature-based方法包括两步:
ELMo是这方面的典型工作
Fine-tuning方式是指在已经训练好的语言模型的基础上,加入少量的task-specific parameters, 例如对于分类问题在语言模型基础上加一层softmax网络,然后在新的语料上重新训练来进行fine-tune。
例如OpenAI GPT 中采用了这样的方法,模型如下所示
Transformer LM + fine-tuning模型示意图
先语言模型采用了Transformer Decoder的方法来进行训练,采用文本预测作为语言模型训练任务,训练完毕之后,加一层Linear Project来完成分类/相似度计算等NLP任务。因此总结来说,LM + Fine-Tuning的方法工作包括两步:
本部分解释来源于:https://zhuanlan.zhihu.com/p/46833276
本论文提出两种大小的BERT结构:
: L=12, H=768, A=12, Total Parameters=110M
: L=24, H=1024, A=16, Total Parameters=340M
其中L表示transformer层数,H表示transformer内部维度,A表示head的数量
其中与OpenAI GPT的参数数量是相同的,模型结构如下所示,BERT是双向的transformer block连接,OpenAI GPT是单向的,只接受左侧信息的,而ELMo虽然也是‘双向’,但是它是分别由从左到右,和从右到左训练之后拼接起来的,但目标函数其实是不同的。ELMo是分别以 和 作为目标函数,独立训练处两个representation然后拼接,而BERT则是以 作为目标函数训练LM。
文章的输入可以是单个句子也可以是句子对(问题,答案)的形式,对于每一个输入的token,由三部分:token, segment and position embeddings求和表示。如下图所示:
其中:
1.token是字符表示,在每一个句子的第一个token都是[CLS],对应于该token的最终隐藏状态(即,Transformer的输出)被用作分类任务的聚合序列表示。如果不是分类任务,将忽略此向量。
2.segment embedding 是当前词所在句子的索引,因为本模型可能会处理句子对的形式(eg.问答任务),用A,B分别表示第一个句子和第二个句子,如果是单个句子任务,那么segment embedding均为A。
3.position embedding 是当前词在整个输入中的位置索引。
此外:
该论文采用WordPiece embeddings,这种方法是针对字符进行处理,将单词分成一个个字符的形式,然后在词的范围内统计字符对出现的次数,每次将次数最多的字符对保存起来,直到循环次数结束。用这种方法可以将单词本身的意思与时态区分开,减小词表的数量。
WordPiece embeddings更详细的部分可看:http://www.mamicode.com/info-detail-2575507.html
这部分介绍两种预训练的方法,也是本论文的核心部分
直觉上,同时采用双向的的训练方法会比单独的一个方向训练或者浅层的两个方向分别训练在连接起来效果好,但是由于在同时进行双向训练时,可能会造成“see itself”这种现象,也就是说要预测的下一个词在给定的序列中已经出现的情况。传统语言模型的数学原理决定了它的单向性。从公式可以看出,传统语言模型的目标是获得在给定序列从头到尾条件概率相乘后概率最大的下一词,而双向模型会导致预测的下一词已经在给定序列中出现了的问题,这就是“自己看见自己”。如图所示(从下向上看),最下行是训练数据A B C D,经过两个bi-lstm操作,需要预测某个词位置的内容。比如第二行第二列A|CD这个结果是第一层bi-lstm在B位置输出内容,包括正向A和反向CD,直接拼接成A|CD。比如第三行第二例ABCD这个结果是前向BCD和反向AB|D拼接结果,而当前位置需要预测的是B,已经在ABCD中出现了,这就会有问题。因而对于Bi-LSTM,只要层数增加,就是会存在“自己看见自己”的问题。
为了解决这种现象, 本文提出了一种masking方法,随机mask一定比例的token,然后仅仅预测这部分被masking的token,本文将这种方法叫做“masked LM”(MLM),就像做完形填空一样,根据上下文信息判断空格处的单词,根据这个时候的hidden 向量,通过softmax判断这个masked token应该是什么。该论文将mask每一个句子中15%的token。
这样做虽然会得到深层的双向预训练模型,但也有两个缺点:
1.由于实验的时候用[mask]代替原本的token进行预测,但是在后续的下游任务进行fine—tuning的时候,输入是没有[mask]的,这样就造成了预训练和微调之间的不匹配,为了减轻这种现象,对于每个句子15%的需要mask的token,并不全用[mask]这个符号替代:
80%的情况用[mask]代替:e.g., my dog is hairy ——my dog is [MASK]
10%的情况用另一个词代替:e.g., my dog is hairy ——my dog is apple
10%的情况不做改变,用原来的词:e.g., my dog is hairy ——my dog is hairy
就是说不全用 [MASK] 是因为在 finetune 到下游任务的时候(例如 POS Tagging)所有词都是已知的,如果模型只在带 [MASK] 的句子上预训练过,那么模型就只知道根据其他词的信息来预测当前词,而不会直接利用这个词本身的信息,会凭空损失一部分信息,对下游任务不利。还有 10% random token 是因为如果都用原 token,模型在预训练时可能会偷懒,不去建模单词间的依赖关系,直接照抄当前词。([MASK] 是以一种显式的方式告诉模型『这个词我不告诉你,你自己从上下文里猜』,从而防止信息泄露。如果 [MASK] 以外的部分全部都用原 token,模型会学到『如果当前词是 [MASK],就根据其他词的信息推断这个词;如果当前词是一个正常的单词,就直接抄输入』。这样一来,在 finetune 阶段,所有词都是正常单词,模型就照抄所有词,不提取单词间的依赖关系了。
以一定的概率填入 random token,就是让模型时刻堤防着,在任意 token 的位置都需要把当前 token 的信息和上下文推断出的信息相结合。这样一来,在 finetune 阶段的正常句子上,模型也会同时提取这两方面的信息,因为它不知道它所看到的『正常单词』到底有没有被动过手脚的。)(解释来源于知乎评论)
2.还有一个缺点是MLM模型只预测每个句子中15%的token,而正常的LM是预测整个句子,所以MLM相比普通的LM收敛速度会慢一些,后续的实验也证明了这一点,但由于MLM在性能上的提高,这一点时间的代价就不那么重要了。
上文提到的MLM方法是针对token级别的预训练,但是由于许多NLP下游任务比如问答系统,自然语言推断是基于句子之间的关系的,为了让模型理解两个句子之间的关系,增加了第二个预训练任务:next sentence prediction
这是一个二分类的任务,用来判断两个句子A,B中,B是不是A的下一句。在训练数据中50%是从真实的上下文中抽取的,50%是随机抽取的(负采样?),在实验中,这一任务可以达到97—98% 的准确率,并在后续的实验中证明了next sentence prediction的作用。
数据集:BooksCorpus (800M words) and English Wikipedia (2,500M words).
(1)256个句子作为一个batch,每个句子最多512个token。
(2)迭代100万步。
(3)总共训练样本超过33亿。
(4)迭代40个epochs。
(5)用adam学习率, β1 = 0.9,β 2 = 0.999。
(6)学习率头一万步保持固定值,之后线性衰减。
(7)L2衰减,衰减参数为0.01。
(8)drop out设置为0.1。
(9)激活函数用GELU代替RELU。
(10)Bert base版本用了16个TPU,Bert large版本用了64个TPU,训练时间4天完成。
(论文定义了两个版本,一个是base版本,一个是large版本。Large版本(L=24, H=1024, A=16, Total Parameters=340M)。base版本( L=12, H=768, A=12, Total Pa- rameters=110M)。L代表网络层数,H代表隐藏层数,A代表self attention head的数量。)
微调阶段根据不同任务使用不同网络模型。在微调阶段,大部分模型的超参数跟预训练时差不多,除了batchsize,学习率,epochs。
最佳的参数根据不同任务而不同,本文给出了一些训练参数对于大部分的任务都有良好的表现:
Batch size: 16, 32
Learning rate (Adam): 5e-5, 3e-5, 2e-5
Number of epochs: 3, 4
本文发现,大的数据集和小的数据集相比对参数没有那么敏感,并且提到微调的速度是很快的,所以可以都进行实验来选择最佳的参数。
在这部分,该论文在11个NLP任务上进行了实验
GLUE数据集具体包含以下数据集:
MNLI Multi-Genre Natural Language Inference (文本蕴含识别) 输入句子对 M,N,判断M,N的关系是蕴含,矛盾,中立 三分类
QQP Quora Question Pairs 输入句子对 判断两个问题是否是等价的 二分类
QNLI Question Natural Language Inference 输入句子对 :一个问题一个句子,判断句子中是否包含问题的回答 二分类
SST-2 The Stanford Sentiment Treebank 输入单个句子 来源于电影评论 判断情感分类 二分类
CoLA The Corpus of Linguistic Acceptability 输入单个句子 判断这个句子在语法上是不是可接受的 二分类
STS-B The Semantic Textual Similarity Benchmark 输入句子对 用1-5判断两个句子的语义相似性 分类
MRPC Microsoft Research Paraphrase Corpus 输入句子对 判断两个句子语义是否等价 二分类
RTE Recognizing Textual Entailment 类似MNLI只是比MNLI的数据集小
WNLI Winograd NLI 这个数据集出了一些问题,所以在实验的时候没有用这个数据集
GLUE数据集上进行的都是分类任务,上文提到token embedding 中的[cls]是用于分类的,用C表示[CLS],在微调过程中只是在BERT的基础上加了一层分类层W,用K表示标签的数量,通过softmax计算分类的结果。
在GLUE数据集上的实验结果如下图所示:
The Standford Question Answering Dataset (SQuAD)这是一个生成式任务,给定的输入是一个问题和一个段落,从段落中找到问题答案(问题的跨度,找到答案在段落中你的开始和结束)如下所示:
在这个任务中,在微调过程中新增的参数是S和E,分别表示答案的start和end,Ti表示经BERT处理后的每一个词的向量表示,如下图所示,每一个词是不是答案的开始的概率计算如下:
同样,每一个词是不是答案的结束的概率也是同样计算,在这个地方加了一个限制是end必须在start之后,实验结果如下所示,TriviaQA是一个问答数据集。EM的基本算法是比较两个字符串的重合率。F1是综合衡量准确率和召回率的一个指标。:
为了评估BERT在序列标注任务上的表现,在CoNLL 2003 Named Entity Recognition (NER) 数据集上进行了微调实验.。这个数据集包括200k训练单词,其中标注为五类: Person, Organization, Location,Miscellaneous, or Other (non-named entity),在微调的时候,在BERT上加了一个分类层来判断是否是名字的一部分,如下图所示:
在实验的过程中,让标注任务与使用的wordpiece方法相匹配,只对词根进行判断,如下所示,不对标记为X的部分进行判断
实验结果如下所示:
The Situations With Adversarial Generations (SWAG) 数据集包括113k sentence-pair,给定一个陈述句和四个备选句子,判断哪一个与陈述句在逻辑上更相关,如下所示:
在这个任务中,将陈述句分别于每一个备选句子作为一个句子对,输入到BERT中,计算两个句子的匹配度,在这个任务中,唯一引入的向量是V(不知道这个V表示的是什么),用V与C的点击来计算两个句子的匹配度,计算公式如下:
实验结果如下:
在这部分研究BERT每个部分的重要性
1. No NSP: 使用“masked LM” (MLM) 但是没有用 “nextsentence prediction” (NSP) task.
2. LTR & No NSP:使用 Left-to-Right (LTR) LM, 而不是MLM. 并且没有使用 NSP,这样就相当于openAI GPT
3.在2的基础上添加一个双向的LSTM
模型的尺寸对实验结果的影响
这里主要讨论Masked LM和普通LM的训练时间问题,可以看到
由于并非所有的NLP任务都可以很容易地用Transformer encoder结构来表示,因此还是需要一个task-specific model结构。同时如果需要fine-tuning的话,transformer encoder模型很大,需要重新训练的话,需要的计算资源比feature-based方法更多,因此如果可以直接用BERT的Transformer的结果的话,就很方面使用了。因此本文做了一个BERT + task-specific model的实验。表明这种方式也是可以有很好的效果的。
结论: