前言
在开始Bert的学习之前,首先应该具备Transformer的基础,因为Bert就是基于Transformer的模型,如果还没有了解Transformer模型,可以查看我的上一篇文章链接: Transformer笔记.
Bert详解
Bert介绍:Bert是基于Transformer的模型,并且是一个迁移能力很强的通用语义表示模型,但是Bert只是运用了Transformer的Encoder部分。Bert的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder。(其中的双向表示模型在处理某一个词的时候,能同时利用前面的词和后面的词两部分信息)
Google对应的Bert版本:Google只是发布了两个版本的Bert,一个是Base版本,一个是Large版本。
1、Base版本: L=12,H=768,A=12,Total Parameters=110M(对Base版本的参数计算详见参考文章链接一)
2、Large版本:L=24,H=1024,A=16, Total Parameters=340M
(L:layer,即transformer的层数;H:输出维度是多少;A:表示的是multi-head attention的个数)
预训练模型:Bert是一个泛化能力较强的预训练模型,即是一个已经用巨大的数据训练出的一个泛化能力很强的模型,并且当我们在特定场景使用时,只需要简单的修改一些输出层,再用我们自己的数据进行一个增量训练,对权重进行一个轻微的调整。
1-1、Bert的一些特点
结构:运用了Transformer的Encoder部分,但是模型结构要比Transformer深,Transformer Encoder包含了6个Encoder block,Bert-base模型包含了12个Encoder block,Bert-large包含了24个Encoder block。
训练:训练主要分为两个阶段:预训练阶段和Fine-tuning阶段。预训练阶段与Word2Vec,ElMo等类似,是在大型数据集上根据一些预训练任务训练得到的。Fine-tuning阶段是后续用于一些下游任务的时候进行微调,例如文本分类,词性标注,问答系统等,Bert无需调整结构就可以在不同的任务上进行微调。
预训练任务1:Bert的第一个预训练任务是Masked LM,即在句子中随机遮盖一部分单词,然后同时利用上下文的信息预测遮盖的单词,这样可以更好地根据全文理解单词的意思。
预训练任务2:BERT的第二个预训练任务是Next Sentence Prediction(NSP),下一句预测任务,这个任务主要是让模型能够更好地理解句子间的关系。
1-2、Bert的结构
上图是Bert的结构图,左侧的图表示了预训练的过程,右边的图是对于具体任务的微调过程。
1-3、输入
Bert增加了一些有特殊作用的标志位:
[CLS]:句子首位标志。
[SEP]:分开两个输入句子的标志。
[MASK]:遮盖句子中一些单词的标志。用mask覆盖之后,再用Bert输出的mask向量预测单词是什么。
为什么playing变成play+##ing:因为Bert里面用了WordPiece的方法,会将单词拆成子词单元(SubWord),所以有的词会拆出词根。
Bert的Embedding(即输入的词向量)是由三种Embedding求和而来的:
Token Embedding:即单词的Embedding
Segment Embedding:句子的Embedding,Bert的训练数据都是由两个句子构成的,那么每个句子都由一个Embedding项来对应到每个单词上。
Position Embedding:位置Embedding,对位置信息进行编码,用来表示每个单词在输入序列中的位置信息。
1-4、Bert预训练
Bert在输入单词的Embedding以后,通过预训练方式训练模型,预训练有两个任务。
第一个任务是Masked LM,在句子中随机用[MASK]替换掉一部分单词,然后将句子传入Bert中编码的每一个单词的信息,最终用[MASK]的编码信息T[MASK]来预测该位置的正确单词。
第二个任务是下一句预测,将句子A和B输入到Bert中,预测B是否是A的下一句,使用[CLS]的编码信息C进行预测。
1-4-1、Masked LM
首先我们需要知道的是,在训练语言模型的时候进行的Mask操作是为了防止信息泄露问题的。信息泄露问题指的是在预测某个单词时,提前知道了这个单词的信息。
Word2Vec的CBOW:
ELMo:
OpenAI GPT:
Bert的作者认为在预测单词时,要同时利用单词left(上文)和right(下文)信息才能最好地预测。将ELMo这种分别进行left-to-right和right-to-left的模型称为浅层双向模型,Bert希望在Transformer Encoder结构上训练出一种深度双向模型,因此提出了Mask LM(深层双向语言模型)这种方法进行训练。
Bert的成功表明,增加模型参数的数量确实是可以提升模型的效果。
Mask LM是用于防止信息泄露的。
训练时只预测 [Mask] 位置的单词,这样就可以同时利用上下文信息。但是在后续使用的时候,句子中并不会出现 [Mask] 的单词,这样会影响模型的性能。因此在训练时采用如下策略,随机选择句子中(输入的Token) 15% 的单词进行 Mask,用其来做上下文预测,在选择为 Mask 的单词中,有 80% 真的使用 [Mask] 进行替换,10% 不进行替换,剩下 10% 使用一个随机单词替换。
例如句子 “my dog is hairy”,选择了单词 “hairy” 进行 Mask,则:
80% 的概率,将句子 “my dog is hairy” 转换为句子 “my dog is [Mask]”。
10% 的概率,保持句子为 “my dog is hairy” 不变。
10% 的概率,将单词 “hairy” 替换成另一个随机词,例如 “apple”。将句子 “my dog is hairy” 转换为句子 “my dog is apple”。
以上是 BERT 的第一个预训练任务 Masked LM。
1-4-2、下一句预测
Bert的第二个预训练任务是NSP,即下一句的预测,给定两个句子A和B,要预测句子B是否是句子A的下一个句子。
BERT 使用这一预训练任务的主要原因是,很多下游任务,例如问答系统 (QA),自然语言推断 (NLI) 都需要模型能够理解两个句子之间的关系,但是通过训练语言模型达不到这个目的。
Bert在进行训练的时候,有一半的概率会选择相连的两个句子A B,有一半的概率会选择不相连的两个句子A B,然后通过[CLS]标志位的输出C来预测句子A的下一句是不是句子B。
1-5、Bert用于具体NLP任务
预训练之后得到的Bert模型在后续用于具体NLP任务的时候可以进行微调(Fine-tuning阶段),Bert模型可以用于多种不同的NLP任务。
预训练后的输出序列依然是[CLS]A[SEP]B[SEP],将其作为Fine-Tune的输入。
句子对分类任务:需要将两个句子传入Bert,然后使用[CLS]的输出值C进行句子对分类。
单个句子的分类任务:输入一个句子,无需[SEP]标志,然后也是用[CLS]的输出值C(即[CLS对应的Transformer最后一层位置上面串接一个softmax分类层即可])进行分类。
问答任务:样本是语句对,Question是问题,Paragraph包含了问题的答案。训练的目标是在Paragraph中找出答案的起始位置(Start,End),将Question和Paragraph传入Bert,然后Bert根据Paragraph所有单词的输出来预测Start和End的位置。
单个句子标注任务:例如命名实体识别,输入单个句子,然后根据Bert对于每个单词的输出T来预测这个单词的类别。
Last:Bert的优缺点
优点:
1、微调成本比较小
2、引入了Masked LM,使用双向LM做模型预训练
3、为预训练模型引入了新的目标NSP,它可以学习句子与句子之间的关系。
4、Transformer Encoder因为有Self-attention机制的缘故,所以Bert自带双向功能。
缺点:
1、[MASK]标记在实际预测中不会出现,训练时用过多的[MASK]会影响模型的表现。
2、Bert对硬件资源的消耗巨大。
参考文章:
一文读懂BERT(原理篇).
【NLP】Google BERT模型原理详解.
彻底理解 Google BERT 模型.
史上最小白之Bert详解.
BERT原理详解.
一本读懂BERT(实践篇).
BERT详解–慢慢来.
Bert时代的创新(应用篇):Bert在NLP各领域的应用进展.
从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史.
未看:
从零实现BERT网络模型.
超详细:
预训练语言模型整理(ELMo/GPT/BERT…).
拥抱脸Transformer社区——GitHub地址.
拥抱脸Transformer社区.
总结
我常常怀疑自己是个废物,但我还是一步步的走在这条路上,不为什么,只是我觉得人活着总得有点追求是吧?
(比如说:钱?哈哈哈哈哈)