《自然语言处理:基于预训练模型的方法》第七章 预训练语言模型-BERT

BERT(Bidirectional Encoder Representation from Transformers)是由Devlin等人在2018年提出的基于深层Transformer的预训练语言模型。BERT不仅充分利用了大规模无标注文本来挖掘其中丰富的语义信息,同时还进一步加深了自然语言处理模型的深度。

这一节将着重介绍BERT的建模方法,其中包括两个基本的预训练任务以及两个进阶预训练任务。最后,介绍如何利用BERT在四类典型的自然语言处理任务上快速搭建相应的模型,并结合代码进行实战。

1.整体结构

首先,从整体框架的角度对BERT进行介绍,了解其基本的组成部分,然后针对每个部分详细介绍,BERT的基本模型结构由多层Transformer构成,包含两个预训练任务:掩码语言模型(Masked Language Model,MLM)和下一个预测(Next Sentence Prediction,NSP)

可以看到,模型的输入由两段文本x^{(1)}x^{(2)}拼接组成,然后通过BERT建模得到上行下文语义表示,最终学习掩码语言模型和下一个句子预测。需要注意的是,掩码语言模型对输入形式并没有特别要求,可以是一段文本也可以是两段文本。而下一个句子预测要求模型的输入是两段文本。因此,BERT在预训练阶段的输入形式统一为两段文本拼接的形式。接下来介绍如何对两段文本建模,得到对应的输入表示。

2.输入表示

BERT的输入表示(Input Representation)由词向量(Token Embedding)、块向量(Segment Embeddings)和位置向量(Position Embedding)之和组成。

 为了计算方便,在BERT中,这三种向量维度均为e,因此可通过下式计算输入序列对应的输入表示\boldsymbol{v}

\boldsymbol{v}=\boldsymbol{v}^{t}+\boldsymbol{v}^{\mathrm{s}}+\boldsymbol{v}^{\mathrm{p}}

式中,\boldsymbol{v}^{t}表示词向量;\boldsymbol{v}^{s}表示块向量;\boldsymbol{v}^{p}表示位置向量,三种向量的大小均为N\times eN表示序列最大长度,e表示词向量维度。接下来介绍这三种向量的计算方法。

(1)词向量

与传统的神经网络模型类似,BERT中的词向量(因为词向量中采用WordPiece分词,所以此处指的是“子词”。为了叙述方便,如无特殊说明,本章节中的词向量均由子词词表构成)同样通过词向量矩阵将输入文本转换成实值向量表示。具体地,假设输入序列x对应的独热向量表示为\boldsymbol{e}^{t} \in \mathbb{R}^{N \times|\mathbb{V}|},其对应的词向量表示\boldsymbol{v}^{t}为:

\boldsymbol{v}^{t}=\boldsymbol{e}^{t}\boldsymbol{W}^{t}

式中,\boldsymbol{W}^{t} \in \mathbb{R}^{|\mathbb{V}| \times e}表示可训练的词向量矩阵;|\mathbb{V}|表示词表大小;e表示词向量维度。

(2)块向量

块向量用来编码当前次属于哪一块(Segment)。输入序列中每个词对应的块编码(Segment Encoding)为当前词所在块的序号(从0开始计数)。

  • 当输入序列是单个块时(如单句文本分类),所有词的块编码均为0;
  • 当输入序列是两个块时(如句对文本分类),第一个句子中每个词对应的块编码为0,第二个句子中每个词对应的块编码为1。

需要注意的是,[CLS]位(输入序列中的第一个标记)和第一个块结尾处的[SEP]位(用于分隔不同块的标记)的块编码均为0。接下来,利用块向量矩阵\boldsymbol{W}^{s}将块编码\boldsymbol{e}^{s} \in \mathbb{R}^{N \times|\mathbb{S}|}转换为实值向量,得到块向量\boldsymbol{v}^{s}:

\boldsymbol{v}^{s}=\boldsymbol{e}^{s}\boldsymbol{W}^{s}

式中,\boldsymbol{W}^{s} \in \mathbb{R}^{|\mathbb{S}| \times e}表示可训练的块向量矩阵;|\mathbb{S}|表示块数量;e表示块向量维度。

(3)位置向量

位置向量用来编码每个词的绝对位置。将输入序列中的每个词按照其下标顺序依次转换为位置独热编码。下一步,利用位置向量矩阵\boldsymbol{W}^{p}将位置独热编码\boldsymbol{e}^{p} \in \mathbb{R}^{N \times N}转换为实值向量,得到位置向量\boldsymbol{v}^{p}

\boldsymbol{v}^{p}=\boldsymbol{e}^{p}\boldsymbol{W}^{p}

式中,\boldsymbol{W}^{p} \in \mathbb{R}^{N \times e}表示可训练的位置向量矩阵;N表示最大位置长度;e表示位置向量维度。

为了描述方便,后续输入表示层的操作统一归纳为如下式:

X=[\mathrm{CLS}] x_{1}^{(1)} x_{2}^{(1)} \cdots x_{n}^{(1)}[\mathrm{SEP}] x_{1}^{(2)} x_{2}^{(2)} \cdots x_{m}^{(2)}[\mathrm{SEP}]

对于给定的原始输入序列X,经过如下处理得到BERT的输入表示\boldsymbol{v}

\boldsymbol{v}=InputRepresentation(X)

式中,\boldsymbol{v} \in \mathbb{R}^{N \times e}表示输入表示层的最终输出结果,即词向量、块向量和位置向量之和;N表示最大序列长度;e表示输入表示维度。

3.基本预训练任务

与GPT不同的是,BERT并没有采用传统的基于自回归的语言建模方法,而是引入了基于自编码(Auto-Encoding)的预训练任务进行训练。BERT的基本预训练任务由掩码语言模型下一个句子预测构成。下面详细介绍两个基本预训练任务。

1.掩码语言模型

传统基于条件概率建模的语言模型只能从左至右(顺序--此处以中文和英文为例,对于阿拉伯语等一些语言来说则是逆序)或者是从右至左(逆序)建模文本序列。如果同时进行顺序建模和逆序建模文本,则会导致信息泄露。

顺序建模表示根据“历史”的词预测“未来”的词。与之相反,逆序建模是根据“未来”的词预测“历史”的词。如果对上述两者同时建模则会导致在顺序建模时“未来”的词已被逆序建模暴露,进而语言模型倾向于从逆序建模中直接输出相应的词,而非通过“历史”词推理预测,从而使得整个语言模型变得非常简单,无法学习深层次的语义信息。对于逆序建模,同样会遇到类似的问题。由于这种问题的存在,在第6章中提到的ELMo模型采用了独立的前向和后向两个语言模型建模文本。

为了真正实现文本的双向建模,即当前时刻的预测同时依赖于“历史”和“未来”,BERT采用了类似完形填空(Cloze)的做法,并称之为掩码语言模型(MLM)。MLM预训练任务直接将输入文本中的部分单词掩码(Mask),并通过深层Transformer模型还原为原单词,从而避免了双向语言模型带来的信息泄露问题,迫使模型使用被掩码词周围的上下文信息还原掩码位置的词。

在BERT中,采用了15%的掩码比例,即输入序列15%的WordPieces子词被掩码。当掩码时,模型使用[MASK]标记替换原单词以表示该位置被掩码。然而,这样会造成预训练阶段和下游任务精调阶段之间的不一致性,因为人为引入[MASK]标记并不会在实际的下游任务中出现。

为了缓解这个问题,当对输入序列掩码时,并非总是将其替换为[MASK],而会按概率选择以下三种操作中的一种:

  • 以80%的概率替换为[MASK]标记
  • 以10%的概率替换为词表中的任意一个随机词
  • 以10%的概率保持原词不变,即不替换

表7-2给出了三种掩码方式的示例,可以看到,当要预测[MASK]标记对应的单词时,模型不仅需要理解当前空缺位置之前的词,同时还要理解空缺位置之后的词,从而达到了双向语言建模的目的。在了解MLM预训练任务的基本方法后,接下来介绍其建模方法。

(1)输入层

由于掩码语言模型并不要求输入一定是两段文本,为了描述方便,假设原始输入文本为x_{1} x_{2} \cdots x_{n},通过上述方法掩码后的输入文本x_{1}^{\prime} x_{2}^{\prime}\cdots x_{n}^{\prime}x_{i}表示输入文本的第i个词,x_{i}^{\prime}表示经过掩码处理后的第i个词。对掩码后的输入文本进行如下处理,得到BERT的输入表示\boldsymbol{v}

X=[CLS]x_{1}^{\prime} x_{2}^{\prime}\cdots x_{n}^{\prime}[SEP]

\boldsymbol{v}=InputRepresentation(X)

式中,[CLS]表示文本序列开始的特殊标记;[SEP]表示文本序列之间的分隔标记。

需要注意的是,如果输入文本的长度n小于BERT的最大序列长度N,需要补齐标记(Padding Token)[PAD]拼接在输入文本后,直至达到BERT的最大序列长度N。例如,在下面的例子中,假设BERT的最大序列长度N=10,而输入序列长度为7(两个特殊标记加上x_{1}x_{5}),需要在输入序列后方添加3个[PAD]补齐标记。

\boldsymbol{h}^{[L]}[CLS]x_{1} x_{2} x_{3}x_{4}x{5}[SEP][PAD][PAD][PAD]

而如果输入序列X的长度大于BERT的最大序列长度N,需要对输入序列X截断至BERT的最大序列长度N。例如,在下面的例子中,假设BERT的最大序列长度N=5,而输入序列长度为7(两个特殊标记加上x_{1}x_{5}),需要对序列截断,使有效序列(输入序列中去除2个特殊标记)长度变为3。

[CLS]x_{1} x_{2} x_{3}[SEP]

为了描述方便,后续将忽略补齐标记[PAD]的处理,并以N表示最大序列长度。

(2)BERT编码层

在BERT编码层中,BERT的输入表示\boldsymbol{v}经过L层Transformer,借助自注意力机制充分学习文本中每个词之间的语义关联。

\boldsymbol{h}^{[l]}=Transformer-Block(\boldsymbol{h}^{[l-1]}),\forall l \in \left \{ 1,2,...,L \right \}

式中,\boldsymbol{h}^{[l]} \in \mathbb{R}^{N \times d}表示第l层Transformer的隐含层输出,同时规定\boldsymbol{h}^{[0]}=\boldsymbol{v},以保持上式的完备性。为了描述方便,略去层与层之间的标记并简化为:

\boldsymbol{h}=Transformer(\boldsymbol{v})

式中,\boldsymbol{h}表示最后一层Transformer的输出,即\boldsymbol{h}^{[L]}。通过上述方法最终得到文本的上下文语义表示\boldsymbol{h} \in \mathbb{R}^{N \times d},其中d表示BERT的隐含层维度。

(3)输出层

由于掩码语言模型仅对输入文本中的部分词进行了掩码操作,因此并不需要预测输入文本中的每个位置,而只需要预测已经掩码的位置。假设集合\mathbb{M}=\left \{ m_{1}, m_{2},...,m_{k}\right \}表示所有掩码位置的下标,k表示总掩码数量。如果输入文本长度为n,掩码比例为15%,则k=\lfloor n \times 15 \%\rfloor。然后,以集合\mathbb{M}中的元素为下标,从输入序列的上下文语义表示\boldsymbol{h}中抽取出对应的表示,并将这些表示进行拼接得到掩码表示\boldsymbol{h}^{m} \in \mathbb{R}^{k \times d}

在BERT中,由于输入表示维度e和隐含层维度d相同,可以直接利用词向量矩阵\boldsymbol{W}^{t} \in \mathbb{R}^{|\mathbb{V}| \times e},公式

\boldsymbol{v}^{t}=\boldsymbol{e}^{t}\boldsymbol{W}^{t}将掩码表示映射到词表控件。对于掩码表示中第i个分量\boldsymbol{h}^{m}_{i},通过下式计算该掩码位置对应的词表上的概率分布P_{i}

P_{i}=\operatorname{Softmax}\left(\boldsymbol{h}_{i}^{\mathrm{m}} \boldsymbol{W}^{\mathrm{t}^{\top}}+\boldsymbol{b}^{\circ}\right)

式中,\boldsymbol{b}^{\circ}\in \mathbb{R}^{|\mathbb{V}|}表示全连接层的偏置。

最后,在得到掩码位置对应的概率分布P_{i}后,与标签y_{i}(即原单词x_{i}的独热向量表示)计算交叉熵损失,学习模型参数。

(4)代码实现

为了使读者加深对MLM预训练任务的理解,此处给出BERT原版的生成MLM训练数据的方法,并详细介绍其中的重点操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值