BERT
《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》有五个关键词,分别是 Pre-training、Deep、Bidirectional、Transformers、和 Language Understanding。其中 pre-training 的意思是,作者认为,确实存在通用的语言模型,先用文章预训练通用模型,然后再根据具体应用,用 supervised 训练数据,精加工(fine tuning)模型,使之适用于具体应用。为了区别于针对语言生成的 Language Model,作者给通用的语言模型,取了一个名字,叫语言表征模型 Language Representation Model。
能实现语言表征目标的模型,可能会有很多种,具体用哪一种呢?作者提议,用 Deep Bidirectional Transformers 模型。假如给一个句子 “能实现语言表征[mask]的模型”,遮盖住其中“目标”一词。从前往后预测[mask],也就是用“能/实现/语言/表征”,来预测[mask];或者,从后往前预测[mask],也就是用“模型/的”,来预测[mask],称之为单向预测 unidirectional。单向预测,不能完整地理解整个语句的语义。于是研究者们尝试双向预测。把从前往后,与从后往前的两个预测,拼接在一起 [mask1/mask2],这就是双向预测 bi-directional。
BERT 的作者认为,bi-directional 仍然不能完整地理解整个语句的语义,更好的办法是用上下文全向来预测[mask],也就是用 “能/实现/语言/表征/../的/模型”,来预测[mask]。BERT 作者把上下文全向的预测方法,称之为 deep bi-directional。如何来实现上下文全向预测呢?BERT 的作者建议使用 Transformer 模型。这个模型由《Attention Is All You Need》一文发明。
这个模型的核心是聚焦机制,对于一个语句,可以同时启用多个聚焦点,而不必局限于从前往后的,或者从后往前的,序列串行处理。不仅要正确地选择模型的结构,而且还要正确地训练模型的参数,这样才能保障模型能够准确地理解语句的语义。BERT 用了两个步骤,试图去正确地训练模型的参数。第一个步骤是把一篇文章中,15% 的词汇遮盖,让模型根据上下文全向地预测被遮盖的词。假如有 1 万篇文章,每篇文章平均有 100 个词汇,随机遮盖 15% 的词汇,模型的任务是正确地预测这 15 万个被遮盖的词汇。通过全向预测被遮盖住的词汇,来初步训练 Transformer 模型的参数。
然后,用第二个步骤继续训练模型的参数。譬如从上述 1 万篇文章中,挑选 20 万对语句,总共 40 万条语句。挑选语句对的时候,其中 210 万对语句,是连续的两条上下文语句,另外 210 万对语句,不是连续的语句。然后让 Transformer 模型来识别这 20 万对语句,哪些是连续的,哪些不连续。
这两步训练合在一起,称为预训练 pre-training。训练结束后的 Transformer 模型,包括它的参数,是作者期待的通用的语言表征模型。
1 Transformer 概览
在整个 Transformer 架构中,它只使用了注意力机制和全连接层来处理文本,因此 Transformer 确实没使用循环神经网络或卷积神经网络实现「特征抽取」这一功能。此外,Transformer 中最重要的就是自注意力机制,这种在序列内部执行 Attention 的方法可以视为搜索序列内部的隐藏关系,这种内部关系对于翻译以及序列任务的性能有显著提升。
如 Seq2Seq 一样,原版 Transformer 也采用了编码器-解码器框架,但它们会使用多个 Multi-Head Attention、前馈网络、层级归一化和残差连接等。下图从左到右展示了原论文所提出的 Transformer 架构、Multi-Head Attention 和点乘注意力。
其中点乘注意力是注意力机制的一般表达形式,将多个点乘注意力叠加在一起可以组成 Transformer 中最重要的 Multi-Head Attention 模块,多个 Multi-Head Attention 模块堆叠在一起就组成了 Transformer 的主体结构,并借此抽取文本中的信息。
点乘注意力其实就是标准 Seq2Seq 模型中的注意力机制。其中 Query 向量与 Value 向量在 NMT 中相当于目标语输入序列与源语输入序列,Query 与 Key 向量的点乘相当于余弦相似性,经过 SoftMax 函数后可得出一组归一化的概率。这些概率相当于给源语输入序列做加权平均,即表示在生成一个目标语单词时源语序列中哪些词是重要的。
Multi-head Attention 其实就是多个点乘注意力并行处理并将最后的结果拼接在一起。这种注意力允许模型联合关注不同位置的不同表征子空间信息,我们可以理解为在参数不共享的情况下,多次执行点乘注意力。
输入序列首先会转换为词嵌入向量,在与位置编码向量相加后可作为 Multi-Head 自注意力模块的输入,自注意力模块表示 Q、V、K 三个矩阵都是相同的。该模块的输出再经过一个全连接层就可以作为编码器模块的输出。
在模型架构上,BERT 使用了非常深的网络,原版 Transformer 只堆叠了 6 个编码器解码器模块,即上图的 N=6。而 BERT 基础模型使用了 12 个编码器模块(N=12),BERT 大模型堆叠了 24 个编码器模块(N=24)。其中堆叠了 6 个模块的 BERT 基础模型主要是为了和 OpenAI GPT 进行对比。
2 模型架构
BERT 的模型架构是一个多层双向 Transformer 编码器,基于 Vaswani 等人 (2017) 描述的原始实现,在 tensor2tensor 库中发布。将层数(即 Transformer 块)表示为 L,将隐藏尺寸表示为 H、自注意力头数表示为 A。在所有实验中,我们将前馈/滤波器尺寸设置为 4H,即 H=768 时为 3072,H=1024 时为 4096。我们要报告在两种模型尺寸上的结果:
BERTBASE: L=12, H=768, A=12, 总参数=110M
BERTLARGE: L=24, H=1024, A=16, 总参数=340M
为了比较,BERTBASE 的模型尺寸与 OpenAI GPT 相当。然而,BERT Transformer 使用双向自注意力机制,而 GPT Transformer 使用受限的自注意力机制,导致每个 token 只能关注其左侧的语境。我们注意到,双向 Transformer 在文献中通常称为「Transformer 编码器」,而只关注左侧语境的版本则因能用于文本生成而被称为「Transformer 解码器」。
输入表示(input representation)
论文的输入表示(input representation)能够在一个token序列中明确地表示单个文本句子或一对文本句子(例如, [Question, Answer])。对于给定token,其输入表示通过对相应的token、segment和position embeddings进行求和来构造。
使用WordPiece嵌入(Wu et al., 2016)和30,000个token的词汇表。用##表示分词。
使用学习的positional embeddings,支持的序列长度最多为512个token。
每个序列的第一个token始终是特殊分类嵌入([CLS])。对应于该token的最终隐藏状态(即,Transformer的输出)被用作分类任务的聚合序列表示。对于非分类任务,将忽略此向量。
句子对被打包成一个序列。以两种方式区分句子。首先,用特殊标记([SEP])将它们分开。其次,添加一个learned sentence A嵌入到第一个句子的每个token中,一个sentence B嵌入到第二个句子的每个token中。
对于单个句子输入,只使用 sentence A嵌入。
3 预训练任务
与 Peters 等人 (2018) 和 Radford 等人 (2018) 不同,我们不使用传统的从左到右或从右到左的语言模型来预训练 BERT,而是使用两个新型无监督预测任务。
3.1 任务 #1:Masked LM
为了训练一个深度双向表示(deep bidirectional representation),研究团队采用了一种简单的方法,即随机屏蔽(masking)部分输入token,然后只预测那些被屏蔽的token。论文将这个过程称为“masked LM”(MLM),尽管在文献中它经常被称为Cloze任务(Taylor, 1953)。
在这个例子中,与masked token对应的最终隐藏向量被输入到词汇表上的输出softmax中,就像在标准LM中一样。在团队所有实验中,随机地屏蔽了每个序列中15%的WordPiece token。与去噪的自动编码器(Vincent et al., 2008)相反,只预测masked words而不是重建整个输入。
虽然这确实能让团队获得双向预训练模型,但这种方法有两个缺点。首先,预训练和finetuning之间不匹配,因为在finetuning期间从未看到[MASK]token。为了解决这个问题,团队并不总是用实际的[MASK]token替换被“masked”的词汇。相反,训练数据生成器随机选择15%的token。例如在这个句子“my dog is hairy”中,它选择的token是“hairy”。然后,执行以下过程:
数据生成器将执行以下操作,而不是始终用[MASK]替换所选单词:
80%的时间:用[MASK]标记替换单词,例如,my dog is hairy → my dog is [MASK]
10%的时间:用一个随机的单词替换该单词,例如,my dog is hairy → my dog is apple
10%的时间:保持单词不变,例如,my dog is hairy → my dog is hairy. 这样做的目的是将表示偏向于实际观察到的单词。
3.2 任务 #2:下一句预测
很多重要的下游任务(如问答(QA)和自然语言推断(NLI))基于对两个文本句子之间关系的理解,这种关系并非通过语言建模直接获得。为了训练一个理解句子关系的模型,我们预训练了一个二值化下一句预测任务,该任务可以从任意单语语料库中轻松生成。具体来说,选择句子 A 和 B 作为预训练样本:B 有 50% 的可能是 A 的下一句,也有 50% 的可能是来自语料库的随机句子。
4 微调过程
Fine-Tuning 阶段,这个阶段的做法和 GPT 是一样的。当然,它也面临着下游任务网络结构改造的问题,在改造任务方面 Bert 和 GPT 有些不同,下面简单介绍一下。通常而言,绝大部分 NLP 问题可以归入上图所示的四类任务中:
一类是序列标注,这是最典型的 NLP 任务,比如中文分词,词性标注,命名实体识别,语义角色标注等都可以归入这一类问题,它的特点是句子中每个单词要求模型根据上下文都要给出一个分类类别。
第二类是分类任务,比如我们常见的文本分类,情感计算等都可以归入这一类。它的特点是不管文章有多长,总体给出一个分类类别即可。
第三类任务是句子关系判断,比如 Entailment,QA,语义改写,自然语言推理等任务都是这个模式,它的特点是给定两个句子,模型判断出两个句子是否具备某种语义关系。
第四类是生成式任务,比如机器翻译,文本摘要,写诗造句,看图说话等都属于这一类。它的特点是输入文本内容后,需要自主生成另外一段文字。