NLP:从Attention到BERT

Posted Babyface Killer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NLP:从Attention到BERT相关的知识,希望对你有一定的参考价值。

写在前面的话

虽然本文作者的主要兴趣并不集中在NLP领域,但该领域的诸多研究成果已经渗透到了机器学习领域的各个方向。且对于文本的处理也是许多机器学习任务的必经之路。经过简单探索,作者发现各种平台上对该领域的研究成果的详解非常丰富。因此本文旨在通过对其他资料的研究,以浅显易懂的语言阐述NLP领域比较火热的研究成果。

Attention

(图中左下角应为编码器)

首先,什么是attention机制?在attention出现之前,编码器的工作就是把序列输入转化成隐藏状态然后把最后一个隐藏状态输出给解码器来进行后面的工作。但这样做的缺陷就是序列开端的信息不能很好地传递给解码器,且因为序列是按照顺序依次进入编码器的,这种顺序信息也会传递给解码器。对于某些任务,顺序信息反而可能会干扰解码器的工作。Attention机制的引入就打破了这些规则从而使得模型有更好的表现。从上图可以看到,编码器在工作过程中把每一个的输出都传入了解码器,而在解码器中有一个特殊的机制(图中叫做对齐模型)来完成attention的任务。这个对齐模型是一个小型的神经网络,它以编码器对于序列每个位置的输出和解码器上一时刻的隐藏状态作为输入,输出一个权重序列。该权重序列的长度与编码器的输入序列长度相同。每个位置的权重越大说明当前解码器越应该集中在该权重对应的输入上。最后将编码器的输出结合权重计算加权平均值作为解码器的输入。这就是attention机制的基本思想。

基于以上的思想,attention模型有下面几种类型:

1. Hard attention:对于输出的权重,只取最大值并在对应位置记为1,其余位置则为0。因此这种类型的attention只会关注某一个点的输入。

2. Soft attention:直接使用softmax输出的权重,这种类型的attention有一定的发散性,使解码器能接受更多的信息。

3. Global attention:使用序列输出的所有隐藏状态

4. Local attention:定义一个窗口[p-w, p+w],只关注该窗口内的隐藏状态。p为模型训练的参数,w为自定义参数。

还有一种就是应用于Transformer的self-attetion

Transformer

首先第一个问题,我们为什么需要transformer?在transformer出现之前,NLP一般时使用循环神经网络来解决问题,这种结构虽然能很有效的捕捉到序列信息,但是它的训练速度和可扩展性并不强。想想看,循环神经网络每一步的输出都要依赖于之前的隐藏状态,这也就意味着这种网络架构不能并行计算,在实际应用中这会大大降低实用性。而transformer中抛弃了循环神经网络的结构,用一种叫做multi-head self-attention的机制来代替循环神经网络的作用,因此在实际的应用中表现大幅提高。下面我们来看看transformer到底是怎么工作的。

 上图清晰的展示了transformer的整体结构,我们把这个大的结构拆分成不同的小部分来讲解。

1. Scaled dot-product attention:这是transformer中最基础的机制,就像乐高积木中最常见也是用处最多的长方形方块。这个机制最难理解的就是Q,K,V这三个变量,作者在阅读了很多相关资料后也并没有找到能清晰解释这三个变量的方法。那么我们可以试着从更高的层面去理解这三个变量。首先这三个变量是通过对输入的词向量进行计算得到的,每个变量对应着各自的权重矩阵 那么我们是不是可以理解为这三个变量试图去捕捉每个词在这三个维度上的特性呢?就好像我们形容一道菜会去说它“色,香,味”俱全,那么对于一句话中的一个词我们是不是也可以用类似的手法来形容它呢?在这里需要注意的是,每个词对应的Q,K,V三个变量是通过神经网络学习各自的权重矩阵中的值得到的,也就是说神经网络会学习到最适合用来形容每个词的三个维度。接下来对于每个词,首先计算Q和序列中每个词的K的相似度(包括自己)然后通过一个softmax层输出一个权重向量。这个操作和之前介绍的attention有异曲同工之妙,区别就在于之前的attention通过循环神经元来看到序列之前的信息而且必须等到之前序列处理完成,而self-attention在序列中的每个位置都能看到该序列中其他位置的信息,这就可以使用并行处理来提高效率。最后输出的权重矩阵再和V进行运算就得到这个结构的输出。

2. Multi-head attetion:理解了之前的结构,这个结构也就很清晰了。为了增加神经网络的拟合能力,并列地使用多个scaled dot-product attention,并且把最后的结果合并在一起,再经过一个权重矩阵的运算输出最终结果。结合之前举的例子,如果我们只用红橙黄绿青蓝紫来形容一道菜的色是不是脑海中根本想象不到这道菜是什么样,那么我们如果我们使用多种形容颜色的形容词来描述这道菜是不是就更为具体。虽然例子举的比较简单,但multi-head attention也是类似的思想。下图比较清晰地展示了从输入到输出的全过程:

3. Positional encoding: 正如我们之前看到的,self-attention可以很好地捕捉序列中的相关信息,但是序列中的位置信息却没办法得到。为了补充这个缺陷,transformer设置了positional encoding来提供序列中的位置信息。位置信息也是以向量的形式表示的,广泛使用的positional encoding有两种。一种是把encoding融入在神经网络的学习过程中,让神经网络去学习序列每个位置的信息。第二种是使用固定的正余弦函数来表达位置信息:

在理解了各个小组件只会再看最开始transformer的结构图就很清晰了,在编码器的一侧,输入序列首先经过位置编码再经过N层的multi-head attention+feed forward之后输入给解码器。在解码器一侧,首先对目标值进行positional encoding,然后使用了一种叫做masked multi-head attention的机制。在这里为什么要使用mask呢?试想我们的任务是翻译“天空是蓝色的", 我们的目标是”sky is blue“。使用mask之后我们的目标就会变为:[sky, sky is, sky is blue], 也就是说我们在翻译每个词的时候只能看到之前翻译过的信息,而不能接触到后面没有翻译的信息,这就避免了解码器作弊的风险。因为在测试时,解码器一侧是无法接受到目标值的,因此只能根据自己之前翻译过的信息和编码器提供的信息来判断下一个词。在经过第一层masked multi-head attention之后,下一层会经过一个叫做encoder-decoder attention的层。这个层的内部操作和之前介绍的scaled dot-product attention是一样的,只是在输入时它接受两种输入,一个来自编码器,一个来自解码器的上一层。来自编码器的输入乘以矩阵之后作为, 来自解码器的输入乘以之后作为V。

在解码器进行运算之后输出的结果会经过一层线性运算再经过softmax就会输出当前每个词的概率,概率最高的词就是当前的输出。正如我们所看到的,transformer是由很多个小组件拼接而成的一个庞大且有效的模型,因此transformer也被广泛应用与各种NLP相关的机器学习任务中。

BERT

首先我们需要明确的一点是BERT是自然语言处理任务中的预训练模型,它不是为了解决某一类任务出现的,而是为了更好地去捕捉文本间的信息。预训练模型就像我们对于语言学习的第一步,当我们了解每个字,词在不同语境的含义时,我们才能用我们学到的这些词来完成其他的任务,比如造句,填空,和改写。对于NLP任务来说,BERT就是负责学习语言的模型,而学习过语言之后具体怎么完成对应的任务就需要设计相应的微调(fine-tune)模型。

在BERT中,只使用了transformer的encoder模块,针对两种任务进行了训练。在BERT中,输入的向量是每个词的embedding。但除了词本身的embedding和positional embedding,还加入了segment embedding。因此BERT的输入为这三种embedding向量之和。之后该输入进入多层transformer就得到了BERT的输出。我们可以把BERT看作transformer的一个具体应用,它的创新点不在于模型的结构,而在于它设置的与训练任务。

1. Masked LM:这个任务也是BERT之所以叫做Bidirectional Encoder Representation for Transformer的原因。在这个任务中,语料库中15%的单词被[mask]屏蔽到,在所有屏蔽的单词中,80%会保持[mask]这个标记,10%会被一个随机词代替,剩下10%会使用该位置的原单词。让我们来思考一下这么做的原因。首先屏蔽15%的单词能够保证剩下85%的信息对于模型的学习过程是足够的。并且随机替换意味着被屏蔽掉的单词可能出现在句子中的任何一个位置,也就是说模型必须结合上下文的信息来对这个位置进行预测,这也就是bidirectional出现的地方。而对于屏蔽掉的单词,如果全部使用[mask]来标记,那么模型很可能学到的只是这个位置需要出现[mask]而不是对应的单词,因此我们需要让模型有几率看到真正出现的单词。而10%的随机词就像数据集中的随机噪音,能够增强模型的拟合能力。

2. Next sentence prediction:这个任务的目标是给两一句话,模型需要判断这两句话在原文中是否为上下文。这个任务的目的在于训练模型对于局部和整体的语义理解。

对于这两个任务,第一个任务使用的是一个多分类问题的损失函数,也就是在对应的[mask]位置,模型是否预测到了正确的类(词),而第二个任务使用的是一个二分类的损失函数(yes or no)。把两个损失函数加在一起,就是BERT在训练过程中使用的损失函数。

写在最后的话

NLP是机器学习领域里一个非常热门且前沿的课题

对于NLP领域里许多模型的理解需要非常强大的背景知识

本文作者对于NLP领域也还处于学习阶段

因此文中有错误请及时指正

转载请注明出处

Sources

1. Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems by Aurelien Geron

2. attention模型方法综述 - 知乎

3. The Illustrated Transformer – Jay Alammar – Visualizing machine learning one concept at a time.

4. 关于BERT的若干问题整理记录-知乎

以上是关于NLP:从Attention到BERT的主要内容,如果未能解决你的问题,请参考以下文章

NLP:从Attention到BERT

NLP:从Attention到BERT

史上最细节的自然语言处理NLP/Transformer/BERT/Attention面试问题与答案

广告行业中那些趣事系列4:详解从配角到C位出道的Transformer

BERT源码分析PART I

NLP-Word Embedding-Attention机制