🦯来自Transformers的双向编码器表示(BERT)
2023-2-8
| 2024-7-16
0  |  阅读时长 0 分钟
type
status
password
date
slug
summary
category
URL
tags
icon

背景

word2vec和GloVe都将相同的预训练向量分配给同一个词,而不考虑词的上下文(上下文无关表示)。考虑到自然语言中丰富的多义现象和复杂的语义,上下文无关表示具有明显的局限性。例如,在“a crane is flying”(一只鹤在飞)和“a crane driver came”(一名吊车司机来了)的上下文中,“crane”一词有完全不同的含义;因此,同一个词可以根据上下文被赋予不同的表示。
包含“上下文敏感”信息的词向量应运而生,例如TagLM(language-model-augmented sequence tagger,语言模型增强的序列标记器) [Peters et al., 2017b]、CoVe(Context Vectors,上下文向量) [McCann et al., 2017]和ELMo(Embeddings from Language Models,来自语言模型的嵌入) [Peters et al., 2018]。

ELMo、GPT与Bert的区别

图14.8.1 ELMo、GPT和BERT的比较
图14.8.1 ELMo、GPT和BERT的比较
  • ELMo: 针对每一种自然语言处理任务,ELMo模型都有一种特定的网络结构。为每一个自然语言处理任务设计一个特定的架构大大削弱了ELMo模型的通用性
  • GPT(Generative Pre Training,生成式预训练)模型为是一种通用的任务无关模型 [Radford et al., 2018]。在自然语言推断、问答、句子相似性和分类等12项任务中都取得了不错的结果。但是GPT采用 Transformer 的 Decoder,只能向前看(从左到右)。在“i went to the bank to deposit cash”(我去银行存现金)和“i went to the bank to sit down”(我去河岸边坐下)的上下文中,由于“bank”对其左边的上下文敏感,GPT将返回“bank”的相同表示(但两句话中的bank明确有不同含义)。
  • Bert:ELMo对上下文进行双向编码,但使用特定于任务的架构;而GPT是任务无关的,但是从左到右编码上下文。BERT(来自Transformers的双向编码器表示)结合了这两个方面的优点。

BERT 模型的输入

BERT 的输入可以是一个句子或者是两个打包在一起的句子(比如 <Question, Answer>)。每个句子序列都会在开头位置添加特殊的分类标记符 [CLS] 作为开始。每个句子序列的结尾都添加特殊的标记符 [SEP] 作为结束。如果是两个打包在一起的句子,那么首先需要用标记符 [SEP] 分割,其次需要用 Segment Embeddings 表示两个不同的句子,如下所示。
notion image
BERT 的输入是由三个 Embedding 相加而成的,分别是 Token Embeddings,Segment Embeddings,Position Embeddings。Bert模型的最终输入为Embedding(batch_size, sentence_length, 768) = Token Embeddings (batch_size, sentence_length, 768) + Segment Embeddings(batch_size, sentence_length, 768) + Position Embeddings(batch_size, sentence_length, 768)
  • Token Embeddings:把输入句子中每个字通过查询字向量表的方式转换为一维向量,作为模型的输入。在 Tokenization 之前,先把特殊标记符 [CLS][SEP] 额外添加到句首和句尾。在 BERT 中,Tokenization 是用 WordPiece 来完成的
      • 当输入为单个文本时,BERT输入序列是特殊类别词元“<cls>”、文本序列的标记、以及特殊分隔词元“<sep>”的连结。段索引为0,嵌入为
      • 当输入为文本对时,BERT输入序列是“<cls>”、第一个文本序列的标记、“<sep>”、第二个文本序列标记、以及“<sep>”的连结。段索引为2,嵌入为
  • Segment Embeddings:用于区分两个不同句子的,第一个句子是 0,第二个句子是 1。如果只有一个句子,那就都使用索引 0
  • Position Embeddings:Position Embeddings 用于给模型提供序列顺序信息的。与 Transformer 中 Positional Encoding 不同,Positional Encoding 通过三角函数计算得到的,而 Position Embeddings 是通过模型训练学习得到的。BERT 使用 Position Embeddings 是因为 BERT 作为通用预训练模型,下游任务通常对词序特征要求比较高,所以选了 Postion Embeddings 这种因通过模型训练学习而潜能比较大的方式

    代码-数据预处理

    下面的get_tokens_and_segments将一个句子或两个句子作为输入,然后返回BERT输入序列的标记及其相应的段索引。
    • 当输入为单个文本时,BERT输入序列是特殊类别词元“<cls>”、文本序列的标记、以及特殊分隔词元“<sep>”的连结。段索引为0,嵌入为
    • 当输入为文本对时,BERT输入序列是“<cls>”、第一个文本序列的标记、“<sep>”、第二个文本序列标记、以及“<sep>”的连结。段索引为2,嵌入为

    数据集形式

    NSP:正样本上下有顺序的句子对;负样本从整个数据集中随机选取一对句子对。
    💡
    注意负样本是从整个数据集,不是从同一文档中选取
    MLM:从一个句子中随机抽取15%的token,参与MLM任务。
    💡
    mask的单词是从一个句子中选取的

    BERT模型网络结构

    BERT 是基于 Transformer 而来的。BERT 使用 个 Transformer Encoder 堆叠而成。至于 Transfomer 的原理在
    🧸
    Transformer模型详解
    有介绍。在论文中的 BERT 模型有两种版本,一种是 ,共有 12层 Encoder;另一种是 ,共有 24 层 Encoder。
    BERT模型参数如下所示,其中 为 Multi-Head Attention 个数; 为词向量长度,同时 Feed Forward 的隐藏层数量设置为 。由于 Encoder 中有 Add & Norm 层,所以虽然模型层数比较多,但不至于导致梯度消失。有时候模型层数不是越多越好的,有人认为低层模型偏向于语法特征学习,高层模型倾向于语义特征学习。
    notion image
     
     
    notion image
    💡
    参数计算过程代码

    代码

    模型实例

    BERT 模型预训练任务

    notion image
    接下来我们看看 BERT 的预训练过程。BERT 的预训练阶段有两个任务,分别是 Masked LMNext Sentence Prediction (NSP)
    • Masked LM:预测句子中被掩盖的词
    • Next Sentence Prediction (NSP):判断输入的两个句子是不是上下句。

    Task 1: Masked Language Modeling(MLM)

    为了双向编码上下文以表示每个词元,论文作者采用了一种随机 Masked 输入序列中的 Token 并预测这个 Token 的方法(可以理解为做完形填空题),这过程被称之为 Masked Language Modeling(MLM)。
    原始训练文本中, 随机的抽取 的token作为参与 Masked LM 任务。而在这 Masked Token 中, 的 Token 用 [MASK] 替换, 的 Token 用任意词替换,剩下的 则不变。最后取这 的 Token 对应的输出做分类来预测其真实值。
    参与 Masked LM 任务的数据中
    • 80%时间为特殊的“<mask>“词元(例如,“this movie is great”变为“this movie is [MASK]”;
    • 10%时间为随机词元(例如,“this movie is great”变为“this movie is drink”);
    • 10%时间内为不变的标签词元(例如,“this movie is great”变为“this movie is great”)。
    💡
    加上 10% 的随机词和 10% 的真实值是让模型知道,每个词都有意义,除了要学习上下文信息,还需要提防每个词,因为每个词都不一定是对的,对于 Bert 来说,每个词都需要很好的理解和预测。
    Q:为什么选中的15%的 token 不能全部用 [MASK]代替,而要用 10% 的 random token 和 10% 的原 token
    [MASK] 是以一种显式的方式告诉模型『这个词我不告诉你,你自己从上下文里猜』,从而防止信息泄露。如果 [MASK] 以外的部分全部都用原token,模型会学到『如果当前词是 [MASK],就根据其他词的信息推断这个词;如果当前词是一个正常的单词,就直接抄输入』。这样一来,在 finetune 阶段,所有词都是正常单词,模型就照抄所有词,不提取单词间的依赖关系了。
    以一定的概率填入 random token,就是让模型时刻堤防着,在任意 token 的位置都需要把当前 token 的信息和上下文推断出的信息相结合。这样一来,在 finetune 阶段的正常句子上,模型也会同时提取这两方面的信息,因为它不知道它所看到的『正常单词』到底有没有被动过手脚的。

    代码

    我们创建mlm实例并对其进行了初始化。BERTEncoder的输出encoded_X表示2个BERT输入序列。我们将pred_positions定义为在encoded_X的任一输入序列中预测的3个tokenmlm的输出表示encoded_X的所有掩蔽位置pred_positions处的预测结果mlm_Y_hat。对于每个预测,结果的大小等于词表的大小。
    通过掩码下的预测词元mlm_Y的真实标签mlm_Y_hat,我们可以计算在BERT预训练中的遮蔽语言模型任务的交叉熵损失。

    Task 2: Next Sentence Prediction (NSP)

    BERT 模型在下游任务中不免地会遇到 QA(Quention-Answer)NLI(Natural Language Inference) 等任务。为此,BERT 增加了第二个预训练任务 Next Sentence Prediction (简称 NSP,也就是预测下一个句子)。其目的是为了理解两个文本句子之间的联系。在 NSP 任务中,BERT 每次训练都会从语料库中随机选取两个句子 A 和 B,其中句子 A 和句子 B 有 的概率是正确相邻的句子,另外 的机率是随机抽取匹配的。
    • 所有参与任务训练的语句都被选中作为句子A.
      • 其中50%的B是原始文本中真实跟随A的下一句话. (标记为IsNext, 代表正样本)
      • 其中50%的B是原始文本中随机抽取的一句话. (标记为NotNext, 代表负样本)
    💡
    在NSP任务中, BERT模型可以在测试集上取得97%-98%的准确率。除此之外,作者特意地说,语料的选取很关键,要选用 document-level 的而不是 sentence-level 的,这样可以具备抽象连续长序列特征的能力。

    代码

    下面的NextSentencePred类使用单隐藏层的多层感知机来预测两个文本句子之间的联系。因为BERT输出的特殊词元[cls]已经对输入的两个句子进行了编码,所以MLP隐藏层的输入是编码后的[cls]词元。
    我们可以看到,NextSentencePred实例的前向推断返回每个BERT输入序列的二分类预测。
    还可以计算两个二元分类的交叉熵损失。
    值得注意的是,上述两个预训练任务中的所有标签都可以从预训练语料库中获得,而无需人工标注。原始的BERT已经在图书语料库 [Zhu et al., 2015]和英文维基百科的连接上进行了预训练。这两个文本语料库非常庞大:它们分别有8亿个单词和25亿个单词。

    整合代码

    在预训练BERT时,最终的损失函数是 MLM 损失函数NSP损失函数 相加。现在我们可以通过实例化三个类BERTEncoderMaskLMNextSentencePred来定义BERTModel类。前向推断返回编码后的BERT表示encoded_X、掩蔽语言模型预测mlm_Y_hat和下一句预测nsp_Y_hat

    BERT的下游任务

    notion image
    在预训练好的BERT模型后面根据特定任务加上相应的网络,可以完成NLP的下游任务,比如文本分类、机器翻译等。不同的 NLP 任务,BERT 模型输出方式也不同。比如:
    • 单文本分类任务:BERT 模型在文本前插入一个 [CLS] 符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类。可以理解为:与文本中已有的其它字/词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个字/词的语义信息
    notion image
    • 序列标注任务:该任务的实际应用场景包括:中文分词 & 新词发现(标注每个字是词的首字、中间字或末字)等。对于该任务,BERT模型利用文本中每个字对应的输出向量对该字进行分类
    • 问答任务:BERT的输出为每个token所对应的encoding vector。假设vector的维度为D,那么整个输出序列为,其中N为整个序列的长度。因为答案由文本中连续的token组成,所以预测答案的过程本质上是确定答案开头和结尾token所在的位置的过程。因此,经过全连接层之后,得到 。其中代表全连接层,为每一个token分别作为答案开头和结尾的logit值,再经过Softmax层之后就得到了相应的概率值。经过数据后处理之后,便可得到预测答案。
    notion image
    • 语句对分类任务(同单文本分类):BERT 模型在文本前插入一个 [CLS] 符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类。
    notion image
    notion image
     

    附件

  • NLP
  • Transformer模型详解Transformers之自定义学习率动态调整
    Loading...
    目录