参考:图解BERT模型:从零开始构建BERT_m0_37477175的博客-CSDN博客
基于 BERT 的项目实战(NER、Classification) - 简书
BERT模型(BidirectionalEncoder Representations from Transformer)是2018年google 提出来的预训练(pre-train)的语言模型(通过无监督的学习掌握了很多自然语言的一些语法或者语义知识,之后在做下游的nlp任务时就会显得比较容易)。它的目标是利用大规模无标注语料训练、获得文本的语义表示(包含丰富语义信息的Representation)。然后将文本的语义表示在特定NLP任务中作微调,最终应用于该NLP任务。
1. 模型的输入/输出
在基于DNN的NLP方法中,文本中的字/词通常都用词向量来表示(一维向量);在此基础上,神经网络会将文本中各个字或词的词向量作为输入,经过一系列复杂的转换后,输出一个一维词向量作为文本的语义表示。特别地,我们通常希望语义相近的字/词在特征向量空间上的距离也比较接近,如此一来,由字/词向量转换而来的文本向量也能够包含更为准确的语义信息。
因此,BERT模型的主要输入是文本中各个字/词的原始词向量,该向量既可以随机初始化,也可以利用Word2Vector等算法进行预训练以作为初始值;输出是文本中各个字/词融合了全文语义信息后的向量表示。
从上图中可以看出,BERT模型通过查询字向量表将文本中的每个字转换为一维向量,作为模型输入;模型输出则是输入各字对应的融合全文语义信息后的向量表示。此外,模型输入除了字向量,还包含另外两个部分:
文本向量:该向量的取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,并与单字/词的语义信息相融合;
位置向量:由于出现在文本不同位置的字/词所携带的语义信息存在差异(比如:“我爱你”和“你爱我”),因此,BERT模型对不同位置的字/词分别附加一个不同的向量以作区分。
最后,BERT模型将字向量、文本向量和位置向量的加和作为模型输入。特别地,在目前的BERT模型中,有时还将英文词汇作进一步切割,划分为更细粒度的语义单位(WordPiece),例如:将playing分割为play和##ing;而对于中文,目前是直接将单字作为构成文本的基本单位。
对于不同的NLP任务,模型输入会有微调,对模型输出的利用也有差异。
1.1 单文本分类任务
对于文本分类任务,BERT模型在文本前插入一个[CLS]符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类。
可以理解为:与文本中已有的其它字/词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个字/词的语义信息。
1.2 语句对分类任务
实际应用场景包括:问答(判断一个问题与一个答案是否匹配)、语句匹配(两句话是否表达同一个意思)等。对于该任务,BERT模型除了添加[CLS]符号并将对应的输出作为文本的语义表示,还对输入的两句话用一个[SEP]符号作分割,并分别对两句话附加两个不同的文本向量以作区分,如下图所示。
1.3 序列标注任务
实际应用场景包括:中文分词&新词发现(标注每个字是词的首字、中间字或末字)、答案抽取(答案的起止位置)等。对于该任务,BERT模型利用文本中每个字对应的输出向量对该字进行标注(分类),如下图所示(B、I、E分别表示一个词的第一个字、中间字和最后一个字)。
根据具体任务的不同,在实际应用中我们可以脑洞大开,通过调整模型的输入、输出将模型适配到真实业务场景中。
2. 模型的预训练任务
BERT实际上是一个语言模型(Language Model)。LM通常采用大规模、与特定NLP任务无关的文本语料进行训练,其目标是学习语言本身应该是什么样的,这就好比我们学习语文、英语等语言课程时,都需要学习如何选择并组合我们已经掌握的词汇来生成一篇通顺的文本。
回到BERT模型上,其预训练过程就是逐渐调整模型参数,使得模型输出的文本语义表示能够刻画语言的本质,便于后续针对具体NLP任务作微调。为了达到这个目的,BERT文章作者提出了两个预训练任务:Masked LM(MLM遮盖词的预测任务)和Next Sentence Prediction(NSP下一个句子预测任务)。
这两个颇具难度的预训练任务,让模型在预训练阶段就对自然语言有了比较深入的学习和认知,而这些知识对下游的nlp任务有着巨大的帮助。当然,想要模型通过预训练掌握知识,需要花费大量的语料,大量的计算资源和大量的时间。但是训练一遍就可以一直使用,这种一劳永逸的工作,依然很值得去做一做。BERT在做下游的有监督nlp任务时就像一个做了充足预习的学生去上课,那效果肯定事半功倍。
BERT模型的预训练过程其实就是在模仿我们学语言的过程。之前的word2vec,glove等Word Embedding技术也是通过无监督的训练让模型预先掌握了一些基础的语言知识,但是Word Embedding技术无论从预训练的模型复杂度(可以理解成学习的能力),以及无监督学习的任务难度都无法和BERT相比。
2.1 Masked LM
Masked LM的任务描述为:给定一句话,随机抹去这句话中的一个或几个词,要求根据剩余词汇预测被抹去的几个词分别是什么(类似完形填空),如下图所示。具体来说,文章作者在一句话中随机选择15%的词汇用于预测。对于这些在原句中被抹去的词汇,80%情况下采用一个特殊符号[MASK]替换,10%情况下采用一个任意词替换,剩余10%情况下保持原词汇不变。
这么做的主要原因是:在后续微调任务中语句中并不会出现[MASK]标记,而且这么做的另一个好处是:预测一个词汇时,模型并不知道输入对应位置的词汇是否为正确的词汇(10%概率),这就迫使模型更多地依赖于上下文信息去预测词汇,并且赋予了模型一定的纠错能力。
2.2 Next Sentence Prediction
其任务描述为:给定一篇文章中的两句话,判断第二句话在文本中是否紧跟在第一句话之后。实际上就是段落重排序的简化版:只考虑两句话,判断是否是一篇文章中的前后句。在实际预训练过程中,从文本语料库中随机选择50%正确语句对和50%错误语句对进行训练,与Masked LM任务相结合,让模型能够更准确地刻画语句乃至篇章层面的语义信息。
BERT模型通过对Masked LM任务和Next Sentence Prediction任务进行联合训练,使模型输出的每个字/词的向量表示都能尽可能全面、准确地刻画输入文本(单句或语句对)的整体信息,为后续的微调任务提供更好的模型参数初始值。
3. 模型结构
Transformer是组成BERT的核心模块,而Attention机制又是Transformer中最关键的部分,因此,下面从Attention机制开始,介绍如何利用Attention机制构建Transformer模块,在此基础上,用多层Transformer组装BERT模型。
3.1 Attention机制
Attention即“注意力机制”,主要作用是让神经网络把“注意力”放在一部分输入上,即:区分输入的不同部分对输出的影响。一个字/词在一篇文本中表达的意思通常与它的上下文有关,因此,字/词的上下文信息有助于增强其语义表示。同时,上下文中的不同字/词对增强语义表示所起的作用往往不同。为了有区分地利用上下文字信息增强目标字的语义表示,就可以用到Attention机制。
3.1.1 Attention
Attention机制主要涉及到三个概念:Query、Key和Value。在上面增强字的语义表示这个应用场景中,目标字及其上下文的字都有各自的原始Value,Attention机制将目标字作为Query、其上下文的各个字作为Key,并将Query与各个Key的相似性作为权重,把上下文各个字的Value融入目标字的原始Value中。如下图所示,Attention机制将目标字和上下文各个字的语义向量表示作为输入,首先通过线性变换获得目标字的Query向量表示、上下文各个字的Key向量表示以及目标字与上下文各个字的原始Value表示,然后计算Query向量与各个Key向量的相似度作为权重,加权融合目标字的Value向量和各个上下文字的Value向量,作为Attention的输出,即:目标字的增强语义向量表示。
3.1.2 Self-Attention
对于输入文本,需要对其中的每个字分别增强语义向量表示,因此,分别将每个字作为Query,加权融合文本中所有字的语义信息,得到各个字的增强语义向量,如下图所示。在这种情况下,Query、Key和Value的向量表示均来自于同一输入文本。
3.1.3 Multi-head Self-Attention
为了增强Attention的多样性,进一步利用不同的Self-Attention模块获得文本中每个字在不同语义空间下的增强语义向量,并将每个字的多个增强语义向量进行线性组合,从而获得一个最终的与原始字向量长度相同的增强语义向量,如下图所示。
举一个例子来帮助理解Multi-head Self-Attention。“南京市长江大桥”,在不同语义场景下对这句话可以有不同的理解:“南京市/长江大桥”,或“南京市长/江大桥”。对于这句话中的“长”字,在前一种语义场景下需要和“江”字组合才能形成一个正确的语义单元;而在后一种语义场景下,它则需要和“市”字组合才能形成一个正确的语义单元。前面提到,Self-Attention旨在用文本中的其它字来增强目标字的语义表示。在不同的语义场景下,Attention所重点关注的字应有所不同。因此,Multi-head Self-Attention可以理解为考虑多种语义场景下目标字与文本中其它字的语义向量的不同融合方式。可以看到,Multi-head Self-Attention的输入和输出在形式上完全相同,输入为文本中各个字的原始向量表示,输出为各个字融合了全文语义信息后的增强向量表示。因此,Multi-head Self-Attention可以看作是对文本中每个字分别增强其语义向量表示的黑盒。
3.2 Transformer Encoder
在Multi-headSelf-Attention的基础上再添加一些“佐料”,就构成了Transformer Encoder。(实际上Transformer模型还包含一个Decoder模块用于生成文本,但BERT并未使用到Decoder模块)。下图展示了Transformer Encoder的内部结构,可以看到,Transformer Encoder在Multi-head Self-Attention之上又添加了三种关键操作:
1. 残差连接(ResidualConnection):将模块的输入与输出直接相加,作为最后的输出。这种操作背后的一个基本考虑是:修改输入比重构整个输出更容易。这样一来,可以使网络更容易训练。
2. Layer Normalization:对某一层神经网络节点作0均值1方差的标准化。
3. 线性转换:对每个字的增强语义向量再做两次线性变换,以增强整个模型的表达能力。这里,变换后的向量与原向量保持长度相同。
Transformer Encoder的输入和输出在形式上还是完全相同,因此,Transformer Encoder同样可以表示为将输入文本中各个字的语义向量转换为相同长度的增强语义向量的一个黑盒。
3.3 BERT model
BERT模型就是把多个Transformer Encoder一层一层地堆叠起来。
在论文中,BERT模型采用的是12层或者24层的双向的Transformer的Encoder(作为特征提取器),两套模型的参数总数分别为110M和340M。在nlp领域,特征提取能力方面的排序大致是Transformer>RNN>CNN。
4. 总结
BERT 就像图像领域的Imagenet,通过高难度的预训练任务,以及强网络模型去预先学习到领域相关的知识,然后去做下游任务。 相较于一些直接使用Naive的模型去做深度学习任务,BERT就像班里赢在起跑线上的孩子,肯定比其他孩子要强出一大截。
参考:
从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 - 知乎
BERT-BiLSMT-CRF-NER 使用谷歌的BERT模型在BLSTM-CRF模型上进行预训练用于中文命名实体识别的Tensorflow代码
https://github.com/macanv/BERT-BiLSTM-CRF-NER
NLP - 基于 BERT 的中文命名实体识别(NER) | Eliyar's Blog
https://github.com/zjy-ucas/ChineseNER
https://github.com/NLPScott/bert-Chinese-classification-task
over