【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)

本文主要用于记录谷歌发表于2018年的一篇论文。该论文提出的BERT模型被各地学者媒体美誉为NLP新一代大杀器。本笔记主要为方便初学者快速入门,以及自我回顾。

论文链接:https://arxiv.org/pdf/1810.04805.pdf

基本目录如下:

  1. 摘要
  2. 核心思想
  3. 总结

------------------第一菇 - 摘要------------------

1.1 论文摘要

本文作者推出了一套新的语言表达模型BERT,全称为Bidirectional Encoder Representations from Transformers。与近年来提出的语言模型不一样的地方在于,BERT不再仅仅是只关注一个词前文或后文的信息,而是整个模型的所有层都去关注其整个上下文的语境信息。实验结果证明,使用预训练过的BERT模型,仅仅在后面再包一层输出层,并对其进行微调训练,就可以取得很不错的结果。具体有多不错,那就是刷爆了NLP领域的11大任务,甚至有几项任务的准确率已经超过了人类。

------------------第二菇 - 核心思想------------------

2.1 论文模型背景

其实BERT模型本身的提出,说实话,并不是什么划时代的产物,只不过他的效果直接刷爆了NLP的各项任务(谷歌家强大的计算资源也是原因之一,想复现这篇论文难度也是很大),看起来比较震撼。所以,该篇论文之所以有那么高的评价,倒不是模型本身有多出色,或者预训练方法有多标新立异,我个人更愿意称其为近年NLP领域突破的集大成者(确实是一个里程碑)。因此,为了能更好的理解这篇文章所表达的内涵,光是看这一篇文章是远远不够的,所以,不同于以往直接深入文章核心,这里先随着论文一起聊聊本文的模型背景。

在NLP领域,语言模型的预训练早已被证明是提高下游模型表现的不二选择,从目前提出的预训练方法来看,主要可以分为两个类型如下,

1)基于特征(Feature-Based)主要的代表有ELMO,用做任务的模型来学习提前预训练好的语言模型内部隐状态的组合参数。(详情可参见我的另一篇论文笔记来讲ELMO的)。

2)微调(Fine-Tuning)主要的代表有OpenAI GPT,用做任务的数据来微调已经训练好的语言模型。

但是以上的预训练都存在一个问题,即在预训练的时候,仅仅考虑了文本的单向顺序,不论是从左到右,还是从右到左,始终不能很好的解决想同时学习这个词汇上下文的信息的问题(ELMO那篇其实也是Bi-directional LM,但确实没有做到同时学习这点,毕竟只是把从左到右和从右到左拼接在一起。。。暂时不知道作者这么说的意思具体指什么,我目前就单纯的理解为作者提出的这个思想核心在于“同时”,而其他NLP的Bi依然停留在分别训练再concact的层面,并没有真正的利用单词的上下文来同时预测这个单词,其实也就是没有脱离传统语言模型的套路)。因此本文的最大的创新点也就在此了,提出了一种新的预训练语言模型的方法(masked language model)。除此之外,本论文的其他几大贡献为,

1)用实验证实利用完整预训练的语言模型,能大大减轻业务端的网络结构的复杂度,上一些轻型的模型就能够取得很好的效果,甚至超过那些专为业务设计的复杂网络结构。

2)作者预训练的这一套BERT模型,刷爆了各大任务指标,希望这一套模型能成为NLP领域的ResNet,开创NLP新时代!

2.2 论文模型结构

论文的模型倒没有什么特别的创新,主要的特征提取层还是Transformer(改用RNN体系当然也可以)那一套(不熟悉的同学可以看我另一篇笔记,里面有详细的介绍),这里直接贴一张原论文的图,想必大家应该也能看懂。(原论文对于BERT还有BASE和LARGE的区别,BASE主要是为了对标比较OPENAI GPT)

【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)_第1张图片
model_structure.png

(PS. 看模型图,这个真的是做到了上下文信息一起进去了,所有的token都有一个指向每一个Transformer的箭头)

以及顺便得再提一下,模型的输入包括三个部分,分别为

1)基于词级别的词向量(分隔以后)- 针对每一个单词的embedding
2)基于位置的向量 - 告诉模型每一个单词在一个句子中的位置信息
3)每一个句子的向量(分隔以后)- 告诉模型这个单词是来自第一个句子还是第二个句子的(训练方法二需要)

具体可以见下图,应该说是很清楚了,

【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)_第2张图片
model_input.png
2.3 论文预训练方法 - Masked LM

接下来重点解析一下作者的预训练方法。为了训练一个深度双向表示模型,作者提出了一种屏蔽一句话中的部分词的训练方法,然后让模型来预测屏蔽的那个词(同比于CBOW,就是根据这个词的上下文,去预测每一个词,损失函数由所有词的loss组成(cross-entropy),而本文的loss只来源于那些被屏蔽的词)。

这里我简单聊一下我对这种训练方法的理解。其实本质上来讲,这种训练方法来源于深度学习中很主流的自编码(AutoEncoder)的方法论,该方法论的核心就是给定一个输入,经过若干层的特征提取变化,最后的输出还是输入本身(比如图像领域,输入一张图片,输出仍是这一张图片,其作用就是更好的提取这张图片的特征表达,是一种非监督的学习方法)。当然为了让模型更加robust,有一种升级的自编码器就是加入一定的噪音(denoising-AutoEncoder),模型的训练目标依旧是要复原输入。再回过来看谷歌提出的这一种训练方法,其实就是输入一句话,我们要复原这一句话,而其中的mask就是我们加的随机的噪音~真的是很巧妙的迁移,解决了同时利用上下文信息的痛点~!

在作者的实验设置中,大约15%的词被随机屏蔽。但是这样的训练方法有两个缺陷。
1)预训练阶段与微调阶段不一致,因为微调阶段是不会有【MASK】存在的,所以考虑到这一层面,作者也不总是将随机选择的词屏蔽为MASK,主要的操作如下描述(相信大家一定看的懂,就不翻译了)

【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)_第3张图片
masked_LM.png

总结来讲就是,模型需要完成的任务有:
1)通过 MASK -> 自己(相对比较难的任务)
2)通过自己 -> 自己(相对简单的任务)
3)通过其他 -> 自己(很难的任务)

并且作者还强调了一下,随机屏蔽的这一点量,似乎并不会影响文本的语言理解(但是必须强调,该训练方法训练出的其实已经不是语言模型了,因为他无法用来生成一句话)。

2)正因为从理论上来讲每一次都只有15%的词是来被训练到的,所以,需要更多预训练的计算与时间成本。而作者也在后文实验证实了该方法确实收敛的较慢,但是效果好呀!(对于这种,只要做好一次,就能一劳永逸的预训练模型,时间和计算成本的增加对谷歌来说确实是小case哈哈)

关于该预训练方法的图解如下【1】

【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)_第4张图片
Masked LM.png

这里得补充说明一点,大家可以注意到,图中的输入不仅仅有一句话中的所有单词,还有一个特殊的标记,[CLS]~关于这个标记,我觉得可以简单理解为,该标记经过特征提取层以后的得到的向量,是能够代表整一个句子的(因为后面的每一个词都会有一个自己对应的向量,而很多下游任务都是希望得到句子的向量表达,所以要么采用暴力的方法,把所有的词汇对应的向量做一个pooling,要么就如谷歌实验设计的一样,加入一个新的标记,让模型对于这个标记去学会整个句子的表达,用于下游的一系列文本分类任务等,看下面的图示也应该能很好理解了,图解也是直接用了[CLS]的输出,并不是误画漏画其他的单词)。

2.3 论文预训练方法 - Next Sentence Prediction

这个预训练方法就比较好直观的理解了,该预训练方法主要是为了增加模型对句子间关系的理解能力(即Bert不仅仅解决一个句子内的关系,他还解决句子间的关系)。因此作者设计了一种二分类预训练方法(注意这里是严格的句子顺序,如果输入是s1-s2,那么顺序不可颠倒,如果变为s2-s1,那就是错误的),让模型来判断,B句是不是A句的后面一句。其中,作者的样本集为平均分布,即一半是正确的,一半是错误的。最终,模型能达到97%-98%的准确率。关于该预训练方法的图解如下【1】。

【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解)_第5张图片
Next Sentence Prediction.png

补充一下,除了[CLS]这个标记,谷歌还另外设计了一个标记[SEP],这个标记就比较简单了,就是单纯的用来区分俩个句子的。而最终的loss也是来源于两种训练方法叠加的一个loss。

2.4 论文预训练与微调的过程

与传统的LM模型训练过程相似,BERT的训练也遵循基本的套路(大家可参见ULMFiT,我的另一篇笔记也有详实的介绍)。作者强调了一下,训练数据集选取的一个关键,就是要选取基于文本的(document-level)而不仅仅是基于句子的(sentence-level),主要是为了让模型学会long contiguous sequences。接下来原论文中就提了一下预训练的细节,有兴趣的同学可以了解一下(大概很难复现?)。至于BERT的实践应用,完全值得另开一篇文章来详细解读,本文就先不具体展开了~

2.5 论文实验结果分析

论文作者把自己提出的整套框架在各大NLP任务上实现了一遍,并且最后还对模型的训练过程做了一些实验对比,这里就不具体展现了。有兴趣的读者可以自行研读。值得一提的是,谷歌有开源的tensor2tensor,有空还是可以读一遍源码,或者工业界的小伙伴,可以学一波应用(资源允许的话)。

但是,仔细考量一下,Bert也并非是无敌的存在,我总结一下其主要的缺点有:
1)这是非语言模型,所以不能适用于生成文本。
2)其训练和预测的过程是不一样的,即预测的时候是没有[MASK]这种东西的,但是训练的时候是有的。
3)效率还是比较低下,没有GPU的小伙伴基本是无缘喽~
哎,不过人家就是效果好啊~哈哈~

------------------第三菇 - 总结------------------

3.1 总结

到这里,整篇论文的核心思想及其创新点已经说清楚了。本论文主要集中在于阐述BERT的核心思想,并且解释了如何实现整一套BERT,附上了详实的对比实验,来验证模型的可行性。

简单总结一下本文就是先罗列了一下该论文的摘要,再具体介绍了一下自己对BERT的理解,以及详细解释了一些BERT涉及的训练方法。总的来说,谷歌这篇论文注定是要开启一个新时代。希望大家读完本文后能进一步加深对该论文的理解。有说的不对的地方也请大家指出,多多交流,大家一起进步~

参考文献:
【1】https://jalammar.github.io/illustrated-bert/

你可能感兴趣的:(【论文笔记】BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(BERT模型理解))