- 因为目前在做的项目需要用到BERT,所以就看了一下BERT提出的那一篇论文~可能理解的不是很透彻,提前感谢各位大佬指正!
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
论文主要内容(包含创新点以及不足)
-
提出了Bidirectional Encoder Representations from Transformers(BERT),BERT主要是由多层双向的Transformer Encoder构成,通过在所有层中联合调节上下文来预训练未标记文本的深层双向表示。因此只需要在预训练模型的基础上增加一个额外的输出层就可以对模型进行微调。效果超级棒!!
-
因为标准语言模型是由左到右的,单向的,这限制了预训练期间使用的体系结构的选择。GPT使用的是多层的Transformer的Decoder,因为前面《attention is all you need》里已将了解过Transformer的Decoder,所以应该知道Decoder里面最底层的带mask的多头注意力机制只会考虑当前要预测的token之前的信息,所以不能考虑双向的信息。
-
受完形填空的影响,BERT使用了Masked LM来缓解前面提到的单向约束问题,实现预训练的深层双向表达。同时还使用了Next Sentence Prediction(NSP)来联合预训练文本对的表示。
-
本文的主要贡献:
- 证明了双向预训练对语言表达的重要性,BERT用MLM的方法实现了在预训练模型中的深层双向表达。
- 使用预训练的方法,减少了许多高度工程化的任务对特定体系结构的需求,BERT是第一个基于微调的表示模型,在一系列下游任务中表现超棒。
- BERT代码和预训练模型均开源(是基于Tensorflow的)
-
相关工作:
- 无监督的基于特征的方法:ELMo。做词嵌入的,是一种无监督的方法(word2vec之类的方法也是无监督的,好像词嵌入都是无监督的吧)
- 无监督微调方法:OpenAI GPT
- 基于监督数据的迁移学习:计算机视觉里面的imageNet
-
BERT介绍及其详细实现
-
模型结构 设层数为L。隐层size为H,多头自注意力机制头的个数的A,则BERT由两种:
- BERT-base : L = 12 , H = 768 , A = 12 总参数110M左右 与OpenAI GPT大小相似,方便比较。
- BERT-lagle : L = 24 , H = 1024 , A = 16 总参数340M左右
-
输入输出表示 为了更好的让BERT去处理下游任务,输入为一个token序列(该序列能够表示一个句子和一对句子,且这里的句子是连续文本的任意跨度)。这里[CLS]对应的最终隐层状态用作分类任务的聚合序列表示,将输入输出表示为E,[CLS]最终隐层向量为C,第i个输入的token最终隐层向量为Ti。
- 每个序列开头为[CLS],如果是两个句子,那两个句子之后要有[SEP]将其分开。
- 要给每一个输入的token都增加一个学习嵌入,表示其属于句子A还是句子B。
- 和Transformer一样,因为只用注意力而没有用CNN或者RNN,对顺序要求不大的同时也不能考虑位置信息了,所以要对每个token加入位置嵌入。
-
预训练BERT 不用传统的从左到右或者从左到右和从右到左浅层串联的方式去训练,而是用两个无监督任务对BERT进行预训练(MLM和NSP)
- MLM 从完形填空中来的灵感,对一个输入input,随机mask掉15%的token,然后预测这些token。在训练过程中,这些被mask掉的token的位置对应的最后一个隐藏层向量经过softmax之后得到当前被mask掉token的预测。考虑到后续在下游任务微调过程中并不会出现[mask],因此并不是完全的使用mask,而是在被选中的15%的mask中:
- 80%会被替换为特殊的token[mask]
- 10%会被替换为一个随机的token
- 10%会保留原token
- NSP 许多的下游任务都建立在理解两个句子之间关系的基础上,所以这里训练了一个理解句子关系的模型。当为每一个预训练示例选择句子A或B时,50%B是A的下一句,50%B是语料库中的随机句子。
- 预训练数据 为了得到长连续序列,使用文档级别的语料库而不是句子级别的语料库是至关重要的。
- MLM 从完形填空中来的灵感,对一个输入input,随机mask掉15%的token,然后预测这些token。在训练过程中,这些被mask掉的token的位置对应的最后一个隐藏层向量经过softmax之后得到当前被mask掉token的预测。考虑到后续在下游任务微调过程中并不会出现[mask],因此并不是完全的使用mask,而是在被选中的15%的mask中:
-
微调BERT 针对不同的下游任务,,通过适当的交换输入输出,增加输出层,端到端的来进行微调。
-
与预训练相比,微调的代价更小。
-
-
实验 介绍了BERT在11个NLP下游任务中的微调结果,在论文和笔记里有写,这里就不再总结。主要是针对GLUE数据集,SQuAD v1.1数据集,SQuAD v2.0数据集和SWAG数据集。(不懂)
-
消融实验 主要是对预训练任务效果,模型大小的影响和基于特征的BERT方法做了消融实验
-
预训练任务结果 将BERT-base当作baseline,使用完全相同的预训练数据,微调方案和超参数来针对两个下游任务,证明了深度双向的重要性。
- 无NSP 只用MLM
- LTR&无NSP 将MLM换成用从左到右的模型
- LTR&无NSP+BiLSTM 增加BiLSTM后效果有提升,但是和BERT-base相比还有一定的差距
- 将LTR和RTL简单串联(未实现) 通过分析效果不好,而且浪费资源
-
模型大小的影响 模型越大,效果越好。在预训练的无监督的语料充足的情况下得到的预训练模型,只需要很少的有监督的数据就能很好的通过微调应用到下游任务中。
-
基于特征的BERT方法 目前为止所有的BERT微调都是在预训练模型中添加一个简单的分类层,并在下游任务中联合微调所有参数,但是这样有两个问题:(不懂)
- 不是所有的任务都能用Transformer的Encoder去解决
- 先计算一次代价大的数据表示,再将其应用到代价小的模型中去进行实验,有更大的计算优势。(我的理解:针对两个任务1和2,训练两个模型分别针对任务1和任务2所花费的代价,要远大于训练一个预训练模型,然后在此基础上针对两个下游任务进行微调所花费的代价。)
- 结论:BERT对微调和基于特征的方法都是有效的。
-
-
结论 总结来看,就是一个语言模型的迁移学习,使用丰富的无监督的数据去预训练,然后将其用于处理广泛的NLP任务。
学到的点
- 和《Attention is all you need》一样,因为整体都没有用到RNN,所有为了更好的考虑位置信息,输入依然使用了位置嵌入。
- 整体的思想:进行预训练然后将其应用到广泛的下游任务中。
不懂的点
- 实验部分针对11个NLP下游任务我并没有很好的理解
- 基于特征的方法我也不是很懂!!!