BERT模型是由谷歌团队于2019年提出的 Encoder-only 的 语言模型,发表于NLP顶会ACL上。原文题目为:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》链接
在前大模型时代,BERT模型可以算是一个参数量比较大的预训练语言模型。在如今的大模型时代,LLM大多遵循GPT提出的Decoder-only的模型范式。BERT也可以算是时代的眼泪了。这篇文章以BERT原文为基础,回顾BERT模型的相关细节。
1 Introduction
BERT 全称为 Bidirectional Encoder Representations from Transformers。
BERT作为一个在大规模预料上预训练的语言模型,可以通过在后面只增加一层输出层并微调,就可以活动广泛下游任务上的SOTA模型
文中作者将NLP的任务分为两类:
- Sentence-Level tasks
- 通过对句子的整体分析来预测句子之间的关系
- 代表:自然语言推理 以及 转述
- Token-Level tasks
- 模型需要在 Token 层面产生细粒度的输出
- 代表:命名实体识别(Named entity recognition)、问答(question answering)
将预训练的语言表征(语言模型)用于下游任务的两种方法:feature-based 以及 fine-tuning
- feature-based approach: ELMo
- 使用包含预训练表征的任务特定架构做为额外特征
- Fine-tuning approach: OpenAI提出的GPT
- 引入最小任务特定参数,通过简单微调所有预训练参数,在下游任务上进行训练
文中提出,标准的语言模型是单向的,这限制了在预训练期间可以使用的架构的选择。例如:GPT 从左向右的架构:每个Token只能与之前的Token进行运算(通过引入casual mask,这也是Decoder模型的通常做法)
文章中指出:对于自然语言处理的任务:集成双向上下文至关重要。在Decoder-only大模型大行其道的今天,这个论断的有效性……
因此,BERT的预训练任务包括以下两部分,以捕获双向上下文:
- Masked language model
- 完形填空:mask输入中的一些Token,根据上下文预测原来的词
- Next Sentence Prediction
- 联合预训练文本对表示
2 Related Work
回顾了Transformer模型:
这里推荐一篇博客,把Transformer模型讲解得很清晰,而且结合了代码,名为:annotated-transformer
3 BERT
BERT模型分为两个阶段:
Pre-training:在不同的预训练任务上对无标签数据进行训练
Fine-tuning:首先使用预训练的参数进行初始化,并使用下游任务的标记数据对所有参数进行微调。每个下游任务都有单独的微调模型
两种规模的BERT模型,其配置以及总体的参数量
BERT-base:L 12,H 768,A 12,110M
BERT-large:L 24,H 1024,A 16,340M
在当年,参数量都还是M级,就已经决定模型很大了,现在都是B级的参数量了,汗-_-||
Input/Output Representations
输入表示:在一个Token序列里既可以表示一对句子,也可以表示单独一个句子
Token embeddings 采用 WordPiece技术
每个序列的第一个标记总是一个特殊的分类标记([CLS])。
该令牌对应的最终隐藏状态作为分类任务的聚合序列表示。
当句子对被打包到一个序列中时,区分句子的方法:
- 引入 [SEP] Token作为句子的分隔
- 为每个Token添加一个学习到的嵌入,指示它是属于句子A还是句子B
每个Token的输入表示 = Token Embeddings + segment Embeddings + position Embeddings
emdedding包含三部分
BERT的激活函数采用 GeLU 替代原始 Transformer 中的 ReLU
G
E
L
U
(
x
)
=
0.5
×
x
×
(
1
+
T
a
n
h
(
2
/
π
×
(
x
+
0.044715
×
x
3
)
)
)
GELU(x)=0.5\times x \times (1+Tanh(\sqrt{2/\pi}\times (x+0.044715\times x^3)))
GELU(x)=0.5×x×(1+Tanh(2/π×(x+0.044715×x3)))
其函数图像如下图所示,与 ReLU不同,GeLU并不是将负数置为0,而是将其置为较小的负数,某种意义上是使得数据更平滑。
3.1 Pre-training BERT
Task #1: Masked LM
简单地随机掩盖输入 Token 的某些百分比,然后预测那些被掩盖的 Token
mask Token 对应的最终隐藏向量被输入到词汇表上的输出 softmax 中,就像在标准LM中一样
文中,在每个序列中随机掩码所有 WordPiece Token 的15%
Mask Token的引入会使得 Pre-train 和 fine-tuning 之间存在不匹配的问题,因为 fine-tuning 过程中不会出现 [MASK] Token
缓解措施:并不总是用 [MASK] Token 来代替要被 “masked” 的词
训练数据生成器随机选择 15% 的 Token 位置进行预测。如果选择第 i 个Token,我们将第 i 个Token替换为
- 80%情况下,[MASK] Token
- 10%情况下,随机Token
- 10%情况下,不变
具体如下图:
该部分的 Loss 为:每个 Token 的最终隐藏向量
T
i
T_i
Ti 将与原始 Token 的 交叉熵
Task #2: Next Sentence Prediction (NSP)
二值化的下一个句子预测任务
为每个预训练例子选择句子A和B,B有 50% 的可能性是 A (标记为 IsNext )之后的实际下一个句子,50% 的可能是从语料库中随机抽取的句子(标记为 NotNext)
损失函数为:
Training loss 是 平均掩蔽LM似然(Mean Masked LM likelihood) 和 平均下一个句子预测似然(Mean Next Sentence Prediction likelihood) 之和
预训练数据
BooksCorpus 以及 English Wikipedia
3.2 Fine-tuning BERT
FineTuning时,BERT传输所有参数来初始化下游任务模型参数,而无所谓下游任务是否需要 [CLS] Token
对于涉及文本对的应用,一种常见的模式是在应用双向交叉注意力之前对文本对进行独立编码
BERT使用自注意力机制将这两个阶段统一起来,因为编码一个具有自注意力的串联文本对有效地包含了两个句子之间的双向交叉注意力(按照 training 数据的处理方法,如果输入为文本对,通过 [SEP] Token 以及 Segment embedding 区别两个句子)
对于每个下游任务,我们只需将特定于任务的输入和输出 plug in BERT,并端到端地微调所有参数
对于Token级的NLP任务,需要将Token的隐层表示被输入到一个输出层,用于得到Token级别的任务输出
对于分类任务,只需将 [CLS] 表示送入输出层进行分类,得到分类结果
在GLEU任务上的微调结构:
4 Experiments
省略
看到这里啦,点赞关注不迷路哦~
O(∩_∩)O