BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
作者:Google
1.Introduction
预训练方法适用于 NLP 任务,包括词嵌入、GPT等方法。NLP 包括两类:第一类叫做句子层面的任务,识别句子的情绪或者连两个句子之间的关系;第二类是词语层面上的任务,识别各个词,对细粒度要求较高。
存在两种预训练的策略,第一种是基于特征的,代表作是 ELMo,对每一下游的任务,构造相关的神经网络训练,作为预训练的特征,可以跟输入一起输入到神经网络里面,将第二类是像 GPT(Generative Pre-trained Transformer) 那样基于微调的。
上面两种存在一个问题,就是他们都是单向的语言模型,下面考虑使用两个方向的信息,也就是 BERT(Bidirectional Encoder Representations from Transformers) ,BERT 减轻了先前提到过的语言模型"masked language model" 所提及的单向限制。(即是每一次选择随机的 token 将其盖住,目标函数就是预测 token,就像是完形填空那样),所以引申出了一个双向 transfomer 模型。除了这个掩码语言模型,文章还训练了“下一个句子预测任务”,判断两个句子在文章中是不是相邻的。
2.Relate works
本人不太熟nlp领域,就不看了。。
3.BERT
模型的预训练是模型在一个没有标签的数据上训练的,在微调的时候,使用预训练好的权重,并且在微调的时候所有权重都参与训练,用的是有标号的数据,每一个下游的任务都会创建一个新的 BERT 模型。
模型架构:文章中没有介绍,说是和transfomer的一样,本文只是调整了三个参数 L(transfomer的块数)、H(隐藏层的维度)、A(注意力机制的头数)。
模型输入:
输入既可以是一个句子,也可以是句子对。使用 WordPiece 方法 embedding,然后用30000个词就可以表示大多数文本了。输入的句子首端添加一个[cls]标识符。对于放括号中的句子序列,需要区分两个句子,用两个方法来区分,第一办法是在每一个句子后面放置一个[sep] 表示seperate,第二种方法是学一个嵌入层,来表示这个词是第一个句子还是第二个句子。
对于词向量来说,进入 BERT 的向量表示是由其本身的 embedding 加上它在哪一个句子的 embedding 和位置的 embedding。
预训练
“完形填空”
如果一个词元是由 wordpiece 生成的话,那么由15%的概率会替换成一个掩码[MASK],但是这样也有问题,在微调的时候模型输入是没有mask的,这会造成两者数据不太一样,解决方法是对于由15%概率选出的词,有80% 的概率是真的替换成 mask,10%的概率是什么随机替换一个词元,还有10%的概率什么都不干,做了一个预测的标记。然后用交叉熵做为损失函数去预测这个词。
“预测下一个句子”
输入序列是句子对,<a, b>, a 和 b 表示两个句子。数据集中的正例和负例五五开。
微调
对比于 transformer 的编码器和解码器架构,BERT 是可以看到序列两端的信息的,但是也付出了不能做机器翻译任务的代价。
对于不同的下游任务设计不同的输入和输出。
4.Experiments
1.Gelu
句子层面的分类任务。将每个句子第一个 token [cls] 对应的最后一层向量拿出来做分类,最后用 softmax 分类。
2.SQuAD
QA 问题,用到两个向量 S 和 E,分别代表开始的词和结尾的词的最后一层的向量。相应的分别对每个词做一个softmax,得到某一个词作为开始或者结尾的概率。
3.SWAG
用来判断两个句子之间关系的数据集,流程也和上面一样。
一个词作为开始或者结尾的概率。
3.SWAG
用来判断两个句子之间关系的数据集,流程也和上面一样。