赞
踩
翻译自:Blog of Jay Alammar;http://jalammar.github.io/illustrated-bert/ ;翻译的同时增加了部分修改以及注解。
2018年是机器学习文本处理领域(或者更准确地说,是自然语言处理或简称为NLP)的一个转折点。我们对如何以最佳方式(能够最好地捕捉潜在的含义和关系)表示单词和句子正在迅速发展。此外,NLP社区已经提出了非常强大的组件,您可以免费下载并在自己的模型中使用这些组件。
NLP领域发展的最新里程碑之一就是BERT的发布,该事件被描述为NLP新时代的开始。BERT模型打破了语言处理任务中的几个记录。论文发布之后,该团队就开源了相关代码,并且我们可以从github上获取相关的预训练模型(Github:Bert)。这是一个重大的进展,因为它使任何人都可以构建一个语言处理的机器学习模型,并将其作为一个随时可用的组件使用——从而节省了从零开始训练语言处理模型所需的时间、精力、知识和资源。
BERT基于最近在NLP社区中出现的一些聪明的想法——包括但不限于半监督序列学习、ELMO、 ULMFiT、OpenAI transformer、以及Transformer。
要准确理解Bert,我们需要了解许多概念。因此,在了解模型本身涉及的概念之前,我们先来看看如何使用BERT。
使用BERT最直接的方法是使用它来对单个文本进行分类。这个模型是这样的:
训练一个这样的模型,你主要只需要训练一个分类器,而只对BERT模型进行一点点修改。这个训练过程叫做fine-tuning,它起源于 Semi-supervised Sequence Learning和 ULMFiT。
可能有些人不熟悉这个话题,既然我们在讨论分类器,那么我们就有必要聊聊机器学习里的监督学习。这意味着我们需要一个带标签的数据集来训练这样的模型。对于这个垃圾邮件分类器示例,数据集将包含一个电子邮件消息列表和一组标签(对于每个消息来说是“垃圾邮件”或“非垃圾邮件”)。
相似的其他用例包括:
现在您已经有了一个关于如何使用BERT的用例,让我们仔细看看它是如何工作的。
论文提出了BERT的两种模型尺寸
每个位置的输出是一个向量(大小为隐藏层size,即在bert base 中为768)。对于我们上面提到的分类任务,我们关注于第一个位置上的输出,即[CLS]标记位置。
这个[CLS]位置的向量可以作为一个分类器的输入。文中采用了只有一层神经网络的分类器便取得了非常好的效果。如果你的任务是多标签的,那么只需要对这个分类器进行一些调整就可以。
对于那些有计算机视觉背景的人来说,这种向量传递应该会让人联想到 VGGNET 这样的模型中卷积部分以及模型的全连接层分类器部分。
这些新发展带来了单词编码的新方式。目前为止,词嵌入是自然语言处理领域的主要力量。 Word2Vec 和 Glove广泛应用于NLP领域。在指出现在改变的内容之前,让我们回顾一下这些方法是如何使用的。
要让机器学习模型处理单词,得让单词需要某种形式的数字表示,以便模型在计算中使用。Word2Vec 表明我们可以通过一个向量来表示一个单词,这个向量包含了单词的语义信息、关系信息甚至语法信息(即表明单词之间的相似性,相关性,比如 上海 和 成都都表示地名,又比如女人与女王和男人与国王之间的关系。)NLP领域很快意识到采用在大规模数据上预训练的单词嵌入向量作为输入相比于在少量数据上直接训练模型更有用。因此,我们可以下载使用Word2Vec 或者 GloVe生成的预训练向量。以下是Glove中单词‘stick’的向量表示(200维):
为了方面描述,后续我们用下面的形式表示一个的单词向量。
如果我们采用Glove表示一个单词,那么无论‘stick’的上下文是什么,它都用相同的向量表示。但是‘stick’在不同情境下有不同的含义。那么为什么不根据内容信息提供对应的单词向量表示呢 — 既能捕捉语义信息又能捕捉上下文信息。因此,一个基于上下文的单词表示方法出现了。
EMLo再给定一个单词向量表示前会关注整个句子,而不是直接分配一个固定的单词表示。它使用双向LSTM来生成这些嵌入表示。
ELMo为NLP任务训练的上下文中提供了重要的一步。ELMo的LSTM模型首先会在一个非常大的数据集上进行预训练,随后便可以将这个作为我们模型中的一个组件进行使用。
ELMo通过训练预测单词序列中的下一个单词获得了语言理解能力,这项任务称为语言建模。这很方便,因为我们有大量的文本数据,这样的模型可以在不需要标签的情况下学习这些数据。
EMLo预训练步骤: “Let’s stick to”作为输入,预测下一个可能出现的单词。当对大型数据集进行训练时,该模型开始学习语言模式。它不太可能准确地猜出这个例子中的下一个单词。更现实的来说,在一个单词‘hang’之后,它会给‘out’分配一个更高的可能性(‘hang out’),而不是‘camera’。
ELMo实际上更进一步,训练了一个双向LSTM——这样它的语言模型不仅有下一个单词的含义,而且还有上一个单词的含义
ELMo通过将隐藏状态(和初始嵌入)以某种方式组合在一起(合并后的加权求和),提出了基于上下文的嵌入。
(注:个人理解就是,在第h层的LSTM模型中,一个单词例如‘stick’包含一个前向的状态表示e1,一个后向状态表示e2,将两者拼接起来得到eh,这样一来每层模型将得到关于‘stick’的表示(e0,e1,…eh),其中e0可以看作是输入向量,然后将这些向量进行加权求和得到‘stick’最终的向量表示。)
ULM-FiT介绍了有效利用模型在预训练时学习到的大量知识的方法 — 不仅仅是嵌入表示,也不仅仅是基于上下文的嵌入表示。ULM-FiT介绍了一个语言模型以及为各种任务微调语言模型的过程。NLP最终找到了一种可能和计算机视觉一样可以进行迁移学习的方法。
Transformer论文和代码的发布,以及它在机器翻译等任务上取得的成果,开始让一些业内人士认为它们可以替代LSTMs。这是因为Transformers处理长距依赖比LSTM更好。
Transformer的Encoder-Decoder结构在机器翻译上效果很好。但是你怎么用它来进行句子分类呢?你将如何使用它来预训练一个可以为其他下游任务进行微调的语言模型呢(下游任务是指那些利用预先训练的模型或组件的监督学习任务)。
事实证明我们不需要对整个transformer模型进行迁移学习以及训练一个可以微调的语言模型。我们可以只用其中的decoder部分。
这个模型堆叠了12层decoder层。因为只采用了decoer层,因此decoder层中并没有普通transformer中encoder-decoder的注意力层,但依然有self-attention层(注:在原始transformer结构中,encoder中主要是self-attention机制加全连接层,而在decoer层中包含一个self-attention,一个encoder-decoder attention,以及一个全连接层)。
有了这个结构,我们可以继续训练模型:使用大量(未标记的)数据集预测下一个单词。比如扔给他7000本书籍让他训练。书本上的信息对于模型训练非常有效,它可以让模型学习到信息之间的关联,这是在tweets这些数据集上难以学到的。
当OpenAI transformer 预训练后我们就可以将他用于一些下游任务了。首先我们还是来看看垃圾邮件分类任务。
OpenAI论文列出了一些输入转换方法处理输入的数据以适应不同的任务。下图显示了模型的结构和执行不同任务时的输入转换。
openAI transformer 提供了一个基于transformer的可微调的预训练模型。但是在从LSTMs到transformer的转换过程中遗漏了一些东西。 ELMo的语言模型是双向的LSTM模型,但是openAI transformer只是训练了一个前向模型。那么我们是否可以训练一个关注前后的基于transformer的模型呢?
为了学习到两个方向上的信息,BERT对其中部分单词做了mask处理
找到一个合适任务训练一个transformer是一困难的问题,早期的BERT采用了“masked language model”解决这个问题。
不仅屏蔽掉15%的输入,BERT还引入了其他一些方式进行改进。有时它会采用随机替换部分词,然后让模型去预测这个位置上原本正确的单词。
如果您回顾OpenAI transformer处理不同任务时的输入转换,您会注意到有些任务需要模型对两句话进行智能化处理(即他们之间是简单的转述吗?给定一个wiki百科条目作为输入,一个关于该条目的问题作为另一个输入,我们可以回答这个问题吗?)
为了使BERT更好地处理多个句子之间的关系,预训练的过程包括一个额外的任务:给定两个句子A和B,预测B是否是A的下一句。
BERT的论文展示了许多使用BERT完成不同任务的方法。
微调方法并不是使用BERT的唯一方法。就像ELMo一样,您可以使用预训练好的BERT来创建基于上下文的单词嵌入。然后您可以将这些嵌入输入给您现有的模型。下面展示了一个与在诸如命名实体识别等任务上微调BERT的结果相差不远的方法。
哪种向量作为上下文嵌入效果最好?我认为这取决于任务。本文考察了6个选项(与微调的得到96.4分的模型相比)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。