Bert模型

1 BERT:公认的里程碑

BERT 模型可以作为公认的里程碑式的模型,但是它最大的优点不是创新,而是集大成者,并且这个集大成者有了各项突破,下面让我们看看 BERT 是怎么集大成者的。

  • BERT 的意义在于:从大量无标记数据集中训练得到的深度模型,可以显著提高各项自然语言处理任务的准确率。
  • 近年来优秀预训练语言模型的集大成者:参考了 ELMO 模型的双向编码思想、借鉴了 GPT 用 Transformer 作为特征提取器的思路、采用了 word2vec 所使用的 CBOW 方法
  • BERT 和 GPT 之间的区别:
    • GPT:GPT 使用 Transformer Decoder 作为特征提取器、具有良好的文本生成能力,然而当前词的语义只能由其前序词决定,并且在语义理解上不足
    • BERT:使用了 Transformer Encoder 作为特征提取器,并使用了与其配套的掩码训练方法。虽然使用双向编码让 BERT 不再具有文本生成能力,但是 BERT 的语义信息提取能力更强
  • 单向编码和双向编码的差异,以该句话举例 “今天天气很{},我们不得不取消户外运动”,分别从单向编码和双向编码的角度去考虑 {} 中应该填什么词:

    • 单向编码:单向编码只会考虑 “今天天气很”,以人类的经验,大概率会从 “好”、“不错”、“差”、“糟糕” 这几个词中选择,这些词可以被划为截然不同的两类
    • 双向编码:双向编码会同时考虑上下文的信息,即除了会考虑 “今天天气很” 这五个字,还会考虑 “我们不得不取消户外运动” 来帮助模型判断,则大概率会从 “差”、“糟糕” 这一类词中选择

      2 BERT 的结构:强大的特征提取能力

  • 如下图所示,我们来看看 ELMo、GPT 和 BERT 三者的区别

图片.png

  • ELMo 使用自左向右编码和自右向左编码的两个 LSTM 网络,分别以 P(wi|w_1,⋯,_wi−1)和 P(wi|wi+1,⋯,wn)
  • 为目标函数独立训练,将训练得到的特征向量以拼接的形式实现双向编码,本质上还是单向编码,只不过是两个方向上的单向编码的拼接而成的双向编码
  • GPT 使用 Transformer Decoder 作为 Transformer Block,以 P(wi|w_1,⋯,_wi−1)
  • 为目标函数进行训练,用 Transformer Block 取代 LSTM 作为特征提取器,实现了单向编码,是一个标准的预训练语言模型,即使用 Fine-Tuning 模式解决下游任务。
  • BERT 也是一个标准的预训练语言模型,它以 P(wi|w_1,⋯,_wi−1,wi+1,⋯,wn)为目标函数进行训练,BERT 使用的编码器属于双向编码器
    • BERT 和 ELMo 的区别在于使用 Transformer Block 作为特征提取器,加强了语义特征提取的能力;
    • BERT 和 GPT 的区别在于使用 Transformer Encoder 作为 Transformer Block,并且将 GPT 的单向编码改成双向编码,也就是说 BERT 舍弃了文本生成能力,换来了更强的语义理解能力。

BERT 的模型结构如下图所示:
Bert详解 - 图4
从上图可以发现,BERT 的模型结构其实就是 Transformer Encoder 模块的堆叠。在模型参数选择上,论文给出了两套大小不一致的模型。
BERTBASE
:L = 12,H = 768,A = 12,总参数量为 1.1 亿
BERTLARGE
:L = 24,H = 1024,A = 16,总参数量为 3.4 亿
其中 L 代表 Transformer Block 的层数;H 代表特征向量的维数(此处默认 Feed Forward 层中的中间隐层的维数为 4H);A 表示 Self-Attention 的头数,使用这三个参数基本可以定义 BERT的量级。
BERT 参数量级的计算公式:
词向量参数+12∗(MultiHeads参数+全连接层参数+layernorm参数)
=(30522+512+2)∗768+768∗2+12∗(768∗768/12∗3∗12+768∗768+768∗3072∗2+768∗2∗2)
=108808704.0≈110M
训练过程也是很花费计算资源和时间的,总之表示膜拜,普通人即便有 idea 没有算力也只能跪着。

3 BERT 之无监督训练

BERT 采用二段式训练方法:

  1. 第一阶段:使用易获取的大规模无标签余料,来训练基础语言模型;
  2. 第二阶段:根据指定任务的少量带标签训练数据进行微调训练。

不同于 GPT 等标准语言模型使用 P(wi|w_1,⋯,_wi−1)
为目标函数进行训练,能看到全局信息的 BERT 使用 P(wi|w_1,⋯,_wi−1,wi+1,⋯,wn)
为目标函数进行训练。
并且 BERT 用语言掩码模型(MLM)方法训练词的语义理解能力;用下句预测(NSP)方法训练句子之间的理解能力,从而更好地支持下游任务。

4 BERT 之语言掩码模型(MLM)

BERT 作者认为,使用自左向右编码和自右向左编码的单向编码器拼接而成的双向编码器,在性能、参数规模和效率等方面,都不如直接使用深度双向编码器强大,这也是为什么 BERT 使用 Transformer Encoder 作为特征提取器,而不使用自左向右编码和自右向左编码的两个 Transformer Decoder作为特征提取器的原因。
由于无法使用标准语言模型的训练模式,BERT 借鉴完形填空任务和 CBOW 的思想,使用语言掩码模型(MLM )方法训练模型。
MLM 方法也就是随机去掉句子中的部分 token(单词),然后模型来预测被去掉的 token 是什么。这样实际上已经不是传统的神经网络语言模型(类似于生成模型)了,而是单纯作为分类问题,根据这个时刻的 hidden state 来预测这个时刻的 token 应该是什么,而不是预测下一个时刻的词的概率分布了。
随机去掉的 token 被称作掩码词,在训练中,掩码词将以 15% 的概率被替换成 [MASK],也就是说随机 mask 语料中 15% 的 token,这个操作则称为掩码操作。注意:在CBOW 模型中,每个词都会被预测一遍。
但是这样设计 MLM 的训练方法会引入弊端:在模型微调训练阶段或模型推理(测试)阶段,输入的文本中将没有 [MASK],进而导致产生由训练和预测数据偏差导致的性能损失。
考虑到上述的弊端,BERT 并没有总用 [MASK] 替换掩码词,而是按照一定比例选取替换词。在选择 15% 的词作为掩码词后这些掩码词有三类替换选项:

  • 80% 练样本中:将选中的词用 [MASK] 来代替,例如:

“地球是[MASK]八大行星之一”

  • 10% 的训练样本中:选中的词不发生变化,该做法是为了缓解训练文本和预测文本的偏差带来的性能损失,例如:

“地球是太阳系八大行星之一”

  • 10% 的训练样本中:将选中的词用任意的词来进行代替,该做法是为了让 BERT 学会根据上下文信息自动纠错,例如:

“地球是苹果八大行星之一”
作者在论文中提到这样做的好处是,编码器不知道哪些词需要预测的,哪些词是错误的,因此被迫需要学习每一个 token 的表示向量,另外作者也表示双向编码器比单项编码器训练要慢,进而导致BERT 的训练效率低了很多,但是实验也证明 MLM 训练方法可以让 BERT 获得超出同期所有预训练语言模型的语义理解能力,牺牲训练效率是值得的。

5 BERT 之下句预测(NSP)

在很多自然语言处理的下游任务中,如问答和自然语言推断,都基于两个句子做逻辑推理,而语言模型并不具备直接捕获句子之间的语义联系的能力,或者可以说成单词预测粒度的训练到不了句子关系这个层级,为了学会捕捉句子之间的语义联系,BERT 采用了下句预测(NSP )作为无监督预训练的一部分。
NSP 的具体做法是,BERT 输入的语句将由两个句子构成,其中,50% 的概率将语义连贯的两个连续句子作为训练文本(连续句对一般选自篇章级别的语料,以此确保前后语句的语义强相关),另外 50% 的概率将完全随机抽取两个句子作为训练文本。
连续句对:[CLS]今天天气很糟糕[SEP]下午的体育课取消了[SEP]
随机句对:[CLS]今天天气很糟糕[SEP]鱼快被烤焦啦[SEP]
其中 [SEP] 标签表示分隔符。 [CLS] 表示标签用于类别预测,结果为 1,表示输入为连续句对;结果为 0,表示输入为随机句对。
通过训练 [CLS] 编码后的输出标签,BERT 可以学会捕捉两个输入句对的文本语义,在连续句对的预测任务中,BERT 的正确率可以达到 97%-98%。

6 BERT 之输入表示

BERT 在预训练阶段使用了前文所述的两种训练方法,在真实训练中一般是两种方法混合使用
由于 BERT 通过 Transformer 模型堆叠而成,所以 BERT 的输入需要两套 Embedding 操作:

  1. 一套为 One-hot 词表映射编码(对应下图的 Token Embeddings);
  2. 另一套为位置编码(对应下图的 Position Embeddings),不同于 Transformer 的位置编码用三角函数表示,BERT 的位置编码将在预训练过程中训练得到(训练思想类似于Word Embedding 的 Q 矩阵)
  3. 由于在 MLM 的训练过程中,存在单句输入和双句输入的情况,因此 BERT 还需要一套区分输入语句的分割编码(对应下图的 Segment Embeddings),BERT 的分割编码也将在预训练过程中训练得到

Bert详解 - 图5
对于分割编码,Segment Embeddings 层只有两种向量表示。前一个向量是把 0 赋给第一个句子中的各个 token,后一个向量是把 1 赋给第二个句子中的各个 token ;如果输入仅仅只有一个句子,那么它的 segment embedding 就是全 0,下面我们简单举个例子描述下:
[CLS]I like dogs[SEP]I like cats[SEP] 对应编码 0 0 0 0 0 1 1 1 1
[SEP]I Iike dogs and cats[SEP] 对应编码 0 0 0 0 0 0 0
Bert详解 - 图6

BERT 下游任务改造

BERT 根据自然语言处理下游任务的输入和输出的形式,将微调训练支持的任务分为四类,分别是句对分类、单句分类、文本问答和单句标注,接下来我们将简要的介绍下 BERT 如何通过微调训练适应这四类任务的要求。

1 句对分类

给定两个句子,判断它们的关系,称为句对分类,例如判断句对是否相似、判断后者是否为前者的答案。
针对句对分类任务,BERT 在预训练过程中就使用了 NSP 训练方法获得了直接捕获句对语义关系的能力。
如下图所示,句对用 [SEP] 分隔符拼接成文本序列,在句首加入标签 [CLS],将句首标签所对应的输出值作为分类标签,计算预测分类标签与真实分类标签的交叉熵,将其作为优化目标,在任务数据上进行微调训练。
Bert详解 - 图7
针对二分类任务,BERT 不需要对输入数据和输出数据的结构做任何改动,直接使用与 NSP 训练方法一样的输入和输出结构就行。
针对多分类任务,需要在句首标签 [CLS] 的输出特征向量后接一个全连接层和 Softmax 层,保证输出维数与类别数目一致,最后通过 arg max 操作(取最大值时对应的索引序号)得到相对应的类别结果。
下面给出句对分相似性任务的实例:
任务:判断句子 “我很喜欢你” 和句子 “我很中意你” 是否相似
输入改写:“[CLS]我很喜欢你[SEP]我很中意你”
取 “[CLS]” 标签对应输出:[0.02, 0.98]
通过 arg max 操作得到相似类别为 1(类别索引从 0 开始),即两个句子相似

2 单句分类

给定一个句子,判断该句子的类别,统称为单句分类,例如判断情感类别、判断是否为语义连贯的句子。
针对单句二分类任务,也无须对 BERT 的输入数据和输出数据的结构做任何改动。
如下图所示,单句分类在句首加入标签 [CLS],将句首标签所对应的输出值作为分类标签,计算预测分类标签与真实分类标签的交叉熵,将其作为优化目标,在任务数据上进行微调训练。
Bert详解 - 图8
同样,针对多分类任务,需要在句首标签 [CLS] 的输出特征向量后接一个全连接层和 Softmax 层,保证输出维数与类别数目一致,最后通过 argmax 操作得到相对应的类别结果。
下面给出语义连贯性判断任务的实例:
任务:判断句子“海大球星饭茶吃” 是否为一句话
输入改写:“[CLS]海大球星饭茶吃”
取 “[CLS]” 标签对应输出:[0.99, 0.01]
通过 arg max 操作得到相似类别为 0,即这个句子不是一个语义连贯的句子

3 文本问答

给定一个问句和一个蕴含答案的句子,找出答案在后这种的位置,称为文本问答,例如给定一个问题(句子 A),在给定的段落(句子 B)中标注答案的其实位置和终止位置。
文本问答任何和前面讲的其他任务有较大的差别,无论是在优化目标上,还是在输入数据和输出数据的形式上,都需要做一些特殊的处理。
为了标注答案的起始位置和终止位置,BERT 引入两个辅助向量 s(start,判断答案的起始位置) 和 e(end,判断答案的终止位置)。
如下图所示,BERT 判断句子 B 中答案位置的做法是,将句子 B 中的每一个次得到的最终特征向量 Ti
经过全连接层(利用全连接层将词的抽象语义特征转化为任务指向的特征)后,分别与向量 s 和 e 求内积,对所有内积分别进行 softmax 操作,即可得到词 Tok m(m∈[1,M]
)作为答案其实位置和终止位置的概率。最后,去概率最大的片段作为最终的答案
Bert详解 - 图9
文本回答任务的微调训练使用了两个技巧:

  1. 用全连接层把 BERT 提取后的深层特征向量转化为用于判断答案位置的特征向量
  2. 引入辅助向量 s 和 e 作为答案其实位置和终止位置的基准向量,明确优化目标的方向和度量方法

下面给出文本问答任务的实例:
任务:给定问句 “今天的最高温度是多少”,在文本 “天气预报显示今天最高温度 37 摄氏度” 中标注答案的起始位置和终止位置
输入改写:“[CLS]今天的最高温度是多少[SEP]天气预报显示今天最高温度 37 摄氏度”
BERT Softmax 结果:

篇章文本 天气 预报 显示 今天 最高温 37 摄氏度
起始位置概率 0.01 0.01 0.01 0.04 0.10 0.80 0.03
终止位置概率 0.01 0.01 0.01 0.03 0.04 0.10 0.80

对 Softmax 的结果取 arg max,得到答案的起始位置为 6,终止位置为 7,即答案为 “37 摄氏度”

4 单句标注

给定一个句子,标注每个次的标签,称为单句标注。例如给定一个句子,标注句子中的人名、地名和机构名。
单句标注任务和 BERT 预训练任务具有较大差异,但与文本问答任务较为相似。
如下图所示,在进行单句标注任务时,需要在每个词的最终语义特征向量之后添加全连接层,将语义特征转化为序列标注任务所需的特征,单句标注任务需要对每个词都做标注,因此不需要引入辅助向量,直接对经过全连接层后的结果做 Softmax 操作,即可得到各类标签的概率分布。
Bert详解 - 图10
由于 BERT 需要对输入文本进行分词操作,独立词将会被分成若干子词,因此 BERT 预测的结果将会是 5 类(细分为 13 小类):

  • O(非人名地名机构名,O 表示 Other)
  • B-PER/LOC/ORG(人名/地名/机构名初始单词,B 表示 Begin)
  • I-PER/LOC/ORG(人名/地名/机构名中间单词,I 表示 Intermediate)
  • E-PER/LOC/ORG(人名/地名/机构名终止单词,E 表示 End)
  • S-PER/LOC/ORG(人名/地名/机构名独立单词,S 表示 Single)

将 5 大类的首字母结合,可得 IOBES,这是序列标注最常用的标注方法。
下面给出命名实体识别(NER)任务的示例:
任务:给定句子 “爱因斯坦在柏林发表演讲”,根据 IOBES 标注 NER 结果
输入改写:“[CLS]爱 因 斯坦 在 柏林 发表 演讲”
BERT Softmax 结果:

BOBES 斯坦 柏林 发表 演讲
O 0.01 0.01 0.01 0.90 0.01 0.90 0.90
B-PER 0.90 0.01 0.01 0.01 0.01 0.01 0.01
I-PER 0.01 0.90 0.01 0.01 0.01 0.01 0.01
E-PER 0.01 0.01 0.90 0.01 0.01 0.01 0.01
S-LOC 0.01 0.01 0.01 0.01 0.01 0.01 0.01

对 Softmax 的结果取 arg max,得到最终地 NER 标注结果为:“爱因斯坦” 是人名;“柏林” 是地名

5 BERT效果展示

无论如何,从上述讲解可以看出,NLP 四大类任务都可以比较方便地改造成 Bert 能够接受的方式,总之不同类型的任务需要对模型做不同的修改,但是修改都是非常简单的,最多加一层神经网络即可。这其实是 Bert 的非常大的优点,这意味着它几乎可以做任何NLP的下游任务,具备普适性,这是很强的。
但是讲了这么多,一个新模型好不好,效果才是王道。那么Bert 采用这种两阶段方式解决各种 NLP 任务效果如何?
在 11 个各种类型的 NLP 任务中达到目前最好的效果,某些任务性能有极大的提升。

Bert详解 - 图11Bert优缺点

优点:
1.利用了文本的双向信息,得到基于上下文的token表示,效果更好
2.计算可并行化
缺点:
1.[MASK]标记在实际预测中不会出现,训练时用过多[MASK]影响模型表现
2.每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token)

BERT 总结

最后,我讲讲我对Bert的评价和看法,我觉得 Bert 是 NLP 里里程碑式的工作,对于后面 NLP 的研究和工业应用会产生长久的影响,这点毫无疑问。但是从上文介绍也可以看出,从模型或者方法角度看,Bert 借鉴了 ELMO,GPT 及 CBOW,主要提出了 Masked 语言模型及 Next Sentence Prediction,但是这里 Next Sentence Prediction 基本不影响大局,而 Masked LM 明显借鉴了 CBOW 的思想。所以说 Bert 的模型没什么大的创新,更像最近几年 NLP 重要进展的集大成者,这点如果你看懂了上文估计也没有太大异议,如果你有大的异议,杠精这个大帽子我随时准备戴给你。
如果归纳一下这些进展就是:首先是两阶段模型,第一阶段双向语言模型预训练,这里注意要用双向而不是单向,第二阶段采用具体任务 Fine-tuning 或者做特征集成;第二是特征抽取要用Transformer 作为特征提取器而不是 RNN 或者 CNN;第三,双向语言模型可以采取 CBOW 的方法去做(当然我觉得这个是个细节问题,不算太关键,前两个因素比较关键)。Bert 最大的亮点在于效果好及普适性强,几乎所有 NLP 任务都可以套用 Bert 这种两阶段解决思路,而且效果应该会有明显提升。可以预见的是,未来一段时间在 NLP 应用领域,Transformer 将占据主导地位,而且这种两阶段预训练方法也会主导各种应用。
另外,我们应该弄清楚预训练这个过程本质上是在做什么事情,本质上预训练是通过设计好一个网络结构来做语言模型任务,然后把大量甚至是无穷尽的无标注的自然语言文本利用起来,预训练任务把大量语言学知识抽取出来编码到网络结构中,当手头任务带有标注信息的数据有限时,这些先验的语言学特征当然会对手头任务有极大的特征补充作用,因为当数据有限的时候,很多语言学现象是覆盖不到的,泛化能力就弱,集成尽量通用的语言学知识自然会加强模型的泛化能力。如何引入先验的语言学知识其实一直是 NLP 尤其是深度学习场景下的 NLP 的主要目标之一,不过一直没有太好的解决办法,而 ELMO/GPT/Bert 的这种两阶段模式看起来无疑是解决这个问题自然又简洁的方法,这也是这些方法的主要价值所在。
对于当前 NLP 的发展方向,我个人觉得有两点非常重要:

  1. 一个是需要更强的特征抽取器,目前看 Transformer 会逐渐担当大任,但是肯定还是不够强的,需要发展更强的特征抽取器;
  2. 第二个就是如何优雅地引入大量无监督数据中包含的语言学知识,注意我这里强调地是优雅,而不是引入,此前相当多的工作试图做各种语言学知识的嫁接或者引入,但是很多方法看着让人牙疼,就是我说的不优雅。

目前看预训练这种两阶段方法还是很有效的,也非常简洁,当然后面肯定还会有更好的模型出现。

转载自