0%

BERT 模型结构与原理

BERT 模型是 Google 发表的论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》而提出的模型。它一种 Transformer 的双向编码器,旨在通过在左右上下文中共有的条件计算来预先训练来自无标号文本的深度双向表示。BERT 在很多 nlp 任务均获得了不错的成绩,具有较强的泛化能力,甚至对于某些特定的任务只需要添加一个输出层来进行 fine-tuning 即可。目前 BERT 模型应用于文本分类,实体提取,问答,翻译等场景

1. BERT 原理结构

BERT 是基于 Transformer 而来的。BERT 使用 \(N\) 个 Transformer Encoder 堆叠而成。至于 Transfomer 的原理这里就不说,上一篇笔记有介绍。在论文中的 BERT 模型有两种版本,一种是 \(BERT_{BASE}\),共有 12层 Encoder;另一种是 \(BERT_{LARGE}\),共有 24 层 Encoder。 \[ \begin{aligned} BERT_{BASE}: L & = 12,\ H = 768,\ A = 12,\ Total Parameters = 110M \\ BERT_{LARGE}: L & = 24,\ H = 1024,\ A = 16,\ Total Parameters = 340M \\ \end{aligned} \]

其中,\(A\) 为 Multi-Head Attention 个数;\(H\) 为词向量长度,同时 Feed Forward 的隐藏层数量设置为 \(4H\)。由于 Encoder 中有 Add & Norm 层,所以虽然模型层数比较多,但不至于导致梯度消失。有时候模型层数不是越多越好的,有人认为低层模型偏向于语法特征学习,高层模型倾向于语义特征学习。

2. BERT 模型输入与输出

BERT 的输入可以是一个句子或者是两个打包在一起的句子(比如 <Question, Answer>)。每个句子序列都会在开头位置添加特殊的分类标记符 [CLS] 作为开始。每个句子序列的结尾都添加特殊的标记符 [SEP] 作为结束。如果是两个打包在一起的句子,那么首先需要用标记符 [SEP] 分割,其次需要用 Segment Embeddings 表示两个不同的句子。如下如所示。

BERT 的输入是由三个 Embedding 相加而成的,分别是 Token Embeddings,Segment Embeddings,Position Embeddings。

  • Token Embeddings:把输入句子中每个字通过查询字向量表的方式转换为一维向量,作为模型的输入。在 Tokenization 之前,先把特殊标记符 [CLS][SEP] 额外添加到句首和句尾。在 BERT 中,Tokenization 是用 WordPiece 来完成的
  • Segment Embeddings:用于区分两个不同句子的,第一个句子是 0,第二个句子是 1。如果只有一个句子,那就都使用索引 0
  • Position Embeddings:Position Embeddings 用于给模型提供序列顺序信息的。与 Transformer 中 Positional Encoding 不同,Positional Encoding 通过三角函数计算得到的,而 Position Embeddings 是通过模型训练学习得到的。BERT 使用 Position Embeddings 是因为 BERT 作为通用预训练模型,下游任务通常对词序特征要求比较高,所以选了 Postion Embeddings 这种因通过模型训练学习而潜能比较大的方式

不同的 NLP 任务,BERT 模型输出方式也不同。比如:

  • 单文本分类任务:对于文本分类任务,BERT 模型在文本前插入一个 [CLS] 符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类。可以理解为:与文本中已有的其它字/词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个字/词的语义信息
  • 语句对分类任务:该任务的实际应用场景包括:问答(判断一个问题与一个答案是否匹配)、语句匹配(两句话是否表达同一个意思)等。对于该任务,BERT 模型除了添加 [CLS] 符号并将对应的输出作为文本的语义表示,还对输入的两句话用一个 [SEP] 符号作分割,并分别对两句话附加两个不同的文本向量以作区分
  • 序列标注任务:该任务的实际应用场景包括:中文分词 & 新词发现(标注每个字是词的首字、中间字或末字)、答案抽取(答案的起止位置)等。对于该任务,BERT模型利用文本中每个字对应的输出向量对该字进行标注(分类)

3. BERT 模型预训练任务

接下来我们看看 BERT 的预训练过程。BERT 的预训练阶段有两个任务,分别是 Masked LM 和 Next Sentence Prediction (NSP)。

3.1 Task 1: Masked LM

为了训练 BERT 深度双向表示,论文作者采用了一种随机 Masked 输入序列中的 Token 并预测这个 Token 的方法(可以理解为做完形填空题)。这过程被称之为 Masked LM(MLM)。在 MLM 任务中,如何 Maked 序列中的 Token?这其中是有一定的方法的。在论文中有提到,作者随机 Mask 输入序列中 \(15\%\) 的 Token。而在 Masked Token 中,\(80\%\) 的 Token 用 [MASK] 替换,\(10\%\) 的 Token 用任意词替换,剩下的 \(\%10\) 则不变。最后取这 \(15\%\) 的 Token 对应的输出做分类来预测其真实值。

3.2 Task 2: Next Sentence Prediction (NSP)

BERT 模型在下游任务中不免地会遇到 QA 和 NLI 等任务。为此,BERT 增加了第二个预训练任务 Next Sentence Prediction (简称 NSP,也就是预测下一个句子)。其目的是为了理解两个文本句子之间的联系。在 NSP 任务中,BERT 每次训练都会从语料库中随机选取两个句子 A 和 B,其中句子 A 和句子 B 有 \(50\%\) 的概率是正确相邻的句子,另外 \(50\%\) 的机率是随机抽取匹配的。除此之外,作者特意地说,语料的选取很关键,要选用 document-level 的而不是 sentence-level 的,这样可以具备抽象连续长序列特征的能力。

参考