现代自然语言处理(NLP):详细概述第三部分:BERT

现代自然语言处理(NLP):BERT

在我之前关于transformers和GPTs的文章中,我们对NLP的时间线和发展进行了系统化的分析。我们已经看到领域是如何从序列到序列建模转向transformers,进而向广义学习方法发展的。在本文中,我们将讨论另一个由Google发表的最具影响力的作品,BERT(双向编码器表示来自transformers)

BERT在NLP领域带来了一些重大改进。虽然BERT的作者没有提出一个非常高尚的架构,但与OpenAI的GPT工作类似,他们无缝地利用了NLP的现代概念,如transformers、预训练和迁移学习,以建立出色的性能。

先决条件

在我们深入理解BERT之前,我们需要了解作者在创建模型时使用或参考了几个其他先前作品的概念和改进。我们需要对这些概念有很好的理解,才能最终理解BERT中使用的概念。这些依赖项包括Transformers、半监督序列学习、ULMFit、OpenAI GPT和ELMo。所以,我已经讨论了除ELMo之外的所有必要主题,我建议先阅读这些文章,然后再继续旅程以获得更好的理解,前提是这些概念不为人所知。至于ELMo,不用担心,我们将从理解这个概念开始。

深度上下文化的词表示

这篇论文是由Allen-AI在2018年发布的。在那之前,像词袋模型、Word2Vec和Glove这样的预训练词嵌入已经受到了广泛的关注,并被证明可以显著提高训练模型的性能。但是,考虑到这些模型得到的词嵌入是基于一种广义方法,而不是基于上下文特定的方法。简单来说,一个词在句子中可以在不同的上下文中使用,根据句子的不同,意义也会发生变化,但表示或嵌入仍然相同。例如,考虑下面这两个句子,

生意谈得很好。

请立即处理这个问题。

词“处理”在这两个句子中都被使用了,但意义根据用法而不同,因此两者不应该用相同的嵌入表示。这就是ELMo的作用。

ELMo的作者提出词嵌入应该表达两个方面:

(i)词在语义上的复杂特征以及

(ii)词在不同的语言环境中的使用方式。

ELMo解决了这两个问题,并根据整个输入句子的函数生成词的嵌入或表示。作者声称,这种方法可以很容易地适应其他模型,并且已经有了一些改进。

架构:作者使用了一个双向LSTM的两层结构来演示这个概念。观察到模型的双向性,即发现前后单词的能力,使得模型能够更好地理解整个句子的上下文,从而提高了嵌入的质量。

架构

方法:作者首先将句子通过一个字符卷积层传递,以创建一个上下文无关的向量(Xk),在LSTM学习问题中,我们经常这样做。对于每个步骤k,上下文向量(Xk)通过2个LSTM层。在第一层(Layer 1)的LSTM之后,产生了2个中间隐藏向量(Hk-forward、Hk-backward),一个用于正向序列,另一个用于反向序列。这两个中间向量相加,创建一个最终的中间向量(Hk-final-layer-1),表示从两个方向接近的单词周围的知识。然后,隐藏状态向量再次通过LSTM模型的第二层(Layer 2)进行传递,为每个步骤或单词k创建另一个最终的中间向量(Hk-final-layer-2)。与第一层LSTM相比,第二个中间向量对上下文的信息具有更好的范围。

最后,将(Hk-final-layer-1)、(Hk-final-layer-2)和(Xk)相加,创建最终的ELMo嵌入,用于特定任务的应用。作者已经证明LSTM模型可以有更多的层,并且非常容易添加到任何特定任务的模型中。这种方法被称为基于特征的方法,与OpenAI等微调的方法相比。

嵌入向量的方程如下所示:

论文链接:https://arxiv.org/pdf/1802.05365.pdf

重要结论:双向LSTM模型可以用于生成基于上下文的嵌入。

然后,最后,我们来到BERT。

BERT:深度双向Transformer的预训练用于语言理解

BERT是由Google的Jacob Devlin和他的同事于2019年提出的。在我们深入讨论BERT的架构和工作之前,让我们澄清一些事情,以免陷入我在探索这些主题时遇到的同样困惑。

在自然语言处理领域,通常有两种类型的模型或任务,即自回归模型自编码模型

自回归模型是指在输入一个句子或一个起始词标记后,生成与输入相关的单词,例如GPT模型。它们非常适用于文本生成、翻译和摘要等任务。

另一种类型的模型是自编码模型,它负责需要理解整个句子上下文以更好地完成某些任务,例如分类、问答、蕴含和命名实体识别等,即在文本中找到特定实体。在我们当前的谷歌搜索中,我们不时看到这种应用,其中网页上与我们搜索查询匹配的行会被突出显示。

现在,不要误会我的意思,我并不是说自回归模型不能用于编码任务,反之亦然,我只是说这些模型更适合在自己的领域中使用。

BERT被设计为一个自编码模型,所以与GPT等模型使用transformer的解码器部分不同,BERT模型仅包含transformer的编码器部分。问题是,为什么?

从架构上看,解码器接收输出,或者在第一步中接收起始标记,应用自注意力并生成下一个单词的概率,因此它只能看到先前的标记或单词,或者只了解先前的上下文,因此它最适合用于自回归模型,因为它基本上是训练来生成单词的。但是编码器是看到整个句子的部分,因此具有整个上下文并能够产生更好的推断结果,这对于自编码任务非常合适。

包含ELMo以支持基于特征的嵌入: BERT论文的作者认为,在某些任务的情况下,只有从左到右的学习方法是付出很高代价的,因为在单词之后的上下文知识会丢失。BERT引入了双向学习,即它将从左到右和从右到左使用自注意力学习单词。作者还专注于迄今为止设计的两种学习方法,即基于特征的学习方法(如ELMo)和基于微调的学习方法(如OpenAI的GPT)。BERT将这两种方法的优点结合在一起。正如我们已经了解的,基于双向LSTM的ELMo很容易集成到模型中。因此,利用编码器一次接收整个句子作为输入,BERT添加了ELMo来生成高质量的上下文相关嵌入,从而提高了性能。

预训练和GPT:作者们也意识到预训练对模型的性能起到了重要作用,是非常必要的。因此,决定在最后使用GPT的预训练和微调技术,以充分发挥基于微调方法的优势。问题在于,GPT的训练只适用于从左到右或正向预测模型,而BERT具有双向数据。另一个问题是,如果使用普通的语言建模任务进行预训练,模型可能会尝试绕过学习,并从从右到左的模型向从左到右的模型泄漏数据,反之亦然。为了消除这些问题,作者们引入了MLM或掩码语言建模任务作为主要的预训练任务,基本上意味着文本中的一个单词会被随机掩盖,模型需要预测被掩盖的单词。

架构和训练:

BERT使用了Vaswani等人提出的transformer的基于编码器的架构,没有太多的改变。BERT发布了两个模型BERT-Base和BERT-Large。BERT-Base包含12个编码器层,一个大小为768的隐藏层向量,每个块中有12个自注意力头,总共约有1.1亿个参数,而BERT-Large有24个编码器层,每个层有16个注意力头,处理大小为1024的向量,总共有3.4亿个参数。

BERT的训练采用两步骤的方法:预训练和微调。在BERT的情况下,预训练使用了两个任务:

  1. 掩码语言建模:在这种情况下,文本中随机选择15%的单词被掩盖,模型需要利用上下文来预测这个单词。
  2. 下一句预测:由于BERT的目标是用于问题回答和蕴含等任务,因此BERT学习分析更长序列的上下文是非常重要的。因此,在这种情况下,将模型传递给一个句子,并告知预测下一个句子。为了进行训练,作者考虑了50%的情况,即下一个句子是真实的下一个句子(IsNextSequence),而在其他50%的情况下不是(IsNotNextSequence)。在模型的顶部添加了一个SoftMax层,提供了这两种情况之间的概率。

对于输入,如果是一个单句,会在前面添加一个[CLS]标记,表示分类任务,正如作者所解释的那样。对于句子相似性和问题回答等任务,作者在中间添加了一个分隔符[SEP]标记以区分句子,然后将句子的上下文嵌入向量放在它们所属的一侧。对于预训练语料库,作者使用了BooksCorpus(8亿个单词)和英文维基百科(25亿个单词)。对于维基百科,我们只提取文本段落,忽略列表、表格和标题。

BERT的预训练和微调

将BERT微调到特定目标任务上非常容易,就像我们在其他基于微调的学习方法中所看到的那样。对于问题回答和相似性等任务,使用分隔符将句子连接起来。将句子的令牌嵌入与分段嵌入相加,以确定单词属于哪个句子,并添加一个位置嵌入,如原始transformer论文中所示,以指示单词在句子中的位置。

创建嵌入

上图显示了用于学习的最终令牌嵌入的创建过程。

论文链接:https://arxiv.org/pdf/1810.04805.pdf

这就是BERT模型的工作原理。现在,我们将简要介绍两个基于BERT的研究工作,这些工作已经被广泛使用并取得了成功。

RoBERTa: 一种鲁棒优化的BERT预训练方法

在2019年,由Meta AI研究团队的刘银汉带领的团队发表了这篇论文,介绍了一种通过鲁棒优化的训练方法来改善BERT的性能。他们使用BERT-Large来测试假设。

作者们做出了以下改变:

  1. 在训练BERT时,添加了分段编码到词嵌入中,以了解词属于哪个句子。RoBERTa移除了这个编码,而是添加了一个分隔符字符来分隔句子。
  2. BERT最初是在16GB的数据上进行训练的,而RoBERTa引入了自己的新数据集,将(1)BERT的数据集(16GB),(2)CC-NEWS的数据集(来自CommonCrawl新闻数据库的英语部分,共76GB),(3)OPENWEBTEXT的数据集(一个开源的WebText重现,文本是从Reddit上的URL中提取的,至少有三个赞同,共38GB),(4)STORIES的数据集(一个包含了CommonCrawl数据子集的数据集,被过滤以匹配Winograd schemas的故事风格,共31GB)进行了合并,总共大小为160GB。作者声称更大的数据集有助于模型获得更紧凑和全面的预训练权重。
  3. BERT使用了MLM(Masked Language Modeling)技术,但掩码是在预处理时进行的,因此有一个掩码的模式,学习模型可以检测到,降低了泛化性能。相反,RoBERTa引入了在运行时进行动态掩码的方式。因此,输入序列在40个迭代周期中进行训练,使用10种不同的掩码模式,每种掩码模式出现4次,带来变化,防止模型学习掩码模式。
  4. RoBERTa的作者发现BERT的预训练目标“下一句预测”稍微降低了模型在下游任务中的性能,因为它影响了模型学习长距离依赖关系的能力。因此,这个预训练目标被移除。
  5. 从之前的研究中,已经确定如果适当增加学习率和小批量大小,可以增加速度和性能优化。最初BERT使用256个序列的批处理进行了100万步的训练。在保持内存需求不变的情况下,RoBERTa的作者发现模型可以使用2K序列批处理进行125k步的训练,或者使用8K批处理进行31k步的训练。在一些剔除实验之后,作者决定采用8K批处理大小。
  6. RoBERTa还对输入表示进行了修改。BERT最初使用30K词汇量的字符级BPE(字节对编码),而RoBERTa将其增加到50K字节级的词单元。

我们已经列出了RoBERTa相对于BERT的所有改进点,这些改进点被后续的研究广泛用于提高BERT的性能。

论文链接:https://arxiv.org/pdf/1907.11692.pdf

接下来,我们将看到BERT的最后一个,也是迄今为止最常用的变体:DistilBERT。

DistilBERT,BERT的精简版本:更小、更快、更便宜、更轻巧

这项工作由hugging face在2020年发表,旨在减少BERT架构和训练模型所需的时间。作者们观察到,训练数据和模型大小随着每个工作的增加呈指数级增长,作为达到最先进性能的必要条件,这使得在内存限制下训练和使用这样的模型变得极其困难。为了解决这个问题,引入了DistilBERT,通过知识蒸馏训练的方法,宣称将BERT模型的大小减少了40%,训练时间减少了60%,同时保留了97%的性能。

知识蒸馏是一种使用两个不同模型的方法,一个被称为教师模型,另一个被称为学生模型。

知识蒸馏[Bucila et al., 2006, Hinton et al., 2015]是一种压缩技术,其中一个紧凑的模型(学生)被训练来复制一个较大的模型(教师)或一组模型的行为。

因此,DistilBERT成为学生模型,BERT成为教师模型。我们知道,在监督学习的情况下,一个训练良好的模型会以非常高的概率预测一个实例是否属于某个类,如果不属于则概率很低。有时,这些值既不太高也不太低。这些情况被学生用来进行优化,因为简单的情况已经被排除,只留下被蒸馏样本进行学习。

DistilBERT模型与BERT非常相似,只是编码器层数增加了2倍。因此,DistilBERT有6个编码器层。学生模型只初始化了BERT的预训练权重,因为它们在架构上非常相似。对于BERT中的每两个层,作者选择了一个层的权重作为DistilBERT每一层的权重。

DistilBERT在与原始BERT模型相同的语料库上进行训练:英文维基百科和多伦多书库的连接。损失函数是Distill Loss的总和,这是一个余弦嵌入损失函数,试图减小教师和学生产生的隐藏向量之间的距离,以及实际的掩码语言建模损失,这在原始BERT论文中使用。

论文链接:https://arxiv.org/pdf/1910.01108.pdf

结论

在本文中,我们尝试了解了BERT及其改进。在本系列的后续部分,我们将看到这一领域的更多发展。

在那之前,愉快阅读!