推荐个讲解视频b站李沐,本文很大部分借鉴了沐神的讲解
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
题目包含了下面几个含义:首先是Pre-training,就是在大量的数据集上预训练,将预训练的参数拿到自己的任务上来做。deep即将网络做的很深,bidirectional transformers表明论文做的工作是双向的transformer,language understanding就是语言理解任务
Abstract
本文为BERT(Bidirectional Encoder Representations from Transformers),即transformer的双向编码器表示。BERT可以从unlabeled的文本中双向的学习特征表示,仅需额外加一个输出层,预训练好的权重就可以在下游任务上进行fine-tune,例如question answering and language inference。
作者在概念上简单,经验上效果更好,并在很多任务上做到了SOTA,这里作者在介绍性能时用到了自己的绝对精度和相对于别的paper的精度,这样写作更好,例如MultiNLI accuracy to 86.7% (4.6% absolute improvement)
Introduction
自然语言可以用pre-training来提升下游任务的性能,一般来讲包含两大类任务
- sentence-level:句子层面的任务,例如句子的情绪的一个识别,两个句子之间的关系
- token-level:词元层面的任务,例如实体命名的识别,如是不是一个街道的名字等等
目前有两种预训练策略,一种是feature-based,如ELMo,另一种是fine-tuning,GPT系列,这两种方法都是单向的语言模型(unidirectional),因为语言模型一般是单向的,我们知道前一句话,才能知道后一句话,但是会带来一定的局限性,如果要做句子层面的分析,比如情感分析,我可以看左边的句子,也可以看右边的句子,再比如QA,我可以看完所有的句子在回答问题,这都是合理的。为此作者使用双向的预训练策略,并设计了两个任务
- masked language model(MLM):作者在一句话中随机mask一些话,然后让模型来预测这些词(类似于完形填空题)
- next sentence prediction(NSP):给两句话,让模型预测这两句话是不是连续的
贡献总结
- 提出了双向的预训练模型,从左到右,从右到左
- 模型fine-tune起来容易,并在sentence和token level的任务上效果很好
- 代码开源
BERT
BERT包含两部分,pre-training和fine-tuning,预训练是在unlabel的数据上训练,微调是在label的下游任务上训练,下面是整个模型的pipeline
Model Architecture
BERT是一个multi-layer bidirectional Transformer encoder,在原始的transformer基础上没有做很大的改动,作者调整了三个参数,L,H,A,其中L是layer的层数,H是隐藏层大小,A是多头的头的数量,一共两个版本
- BERT base:L=12,H=768,A=12
- BERT large:L=24,H=1024,A=16
BERT large的深度L计算是线性关系,H是平方关系,因此L变为两倍,H大约为1.5倍;A为16是因为每个head维度固定在64维
Input/Output Representations
输入可以是一段句子也可以是句子对,sentence指的是任意连续文本,sequence指的是一个sentence或者是两个sentence连在一起(将两个sentence连在一起是有一些下游任务要输入两个句子)
切词方法
切词方法采用的是WordPiece,一般来说使用空格进行切词,但是这样会有一些问题,比如如果某个词出现的频率很低,如果将他算为一个tokend的话,字典长度很大,可学习参数都在字典中了,于是就将他切成一个个小片段,每个小片段出现的频率很高,比如wordpiece这个单词,切成word和piece这两个小片段。切完词后,我们在每个sequence之前加入([CLS])用来分类,除此之外,在每个sentence最后加入([SEP])来区分不同的sentence,如之前的Pipeline所示,整体为「cls, token, token, …, token, seq, token, token, …, token, seq」
位置编码
- token embedding:token本身的嵌入
- segment embedding:嵌入句子信息,比如第一句,第二句
- position embedding:每个token的位置信息
训练方法
- 有两个训练任务,第一个是Mask Language Model(MLM)
对于用WordPiece生成的token,有15%的概率将其mask掉([MASK]),并用网络来预测mask的token,而不是预测整个序列,但这样会带来一些问题:网络在微调的时候是没有mask的,所以对这些mask的词作者采取了以下策略
- 80%的概率真的将其mask掉,即token->([MASK]),例如my dog is hairy->my dog is [MASK]
- 10%的概率变为其他token,即token->([其他]),例如my dog is hairy->my dog is apple
- 10%的概率不变,即token->([不变]),例如my dog is hairy->my dog is hairy
这个比例是通过ablation来选取的,变为其他token主要为了加入一些噪声
- 第二个是Next Sentence Prediction(NSP)
我们的输入sequence有两个sentence A和B,有50%的概率B真的在A之后,有50%的概率B不在A之后,
Input=[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]
Label = IsNext
Input = [CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]
Label = NotNext
注意这里有一个井号#,他本身是一个单词flightless,但是因为不常见,所以被wordpiece分成了fight和less两个词
数据集
数据集采用了两个,BooksCorpus(800M words)以及English Wikipedia(2500M words),第二个是比价好下载的
Conclusion
目前预训练的方法在NLP中效果很好,双向的想法可以在low-resource中取得很好的效果