NLP-学习之路-9

2021-01-09

Attention Models Specification

1. Seq2Seq + Attention

这里我们将会以Neural Machine Translation(NMT)做例子。

1.1. Seq2Seq

基本介绍就不说了,这里分析一下Seq2Seq的缺点:information bottleneck。因为Seq2Seq的input和output是变长的,而中间的memory(encoder hidden state)是定长的,所以如果输入序列很长的话,会导致靠前的信息被稀释,然后造成信息丢失。而且,后面的输入会得到更大的权重。

image-20201229151058849

Seq2Seq在短序列数据上表现得很好,但是长序列就不太行了。

1.2. Alignment

Alignment Scores其实指的是Attention Weights.

1.3. Attention

Attention的3个重要components: key, value and query. Key 和 Value是成对的(很多时候key和value是一样的),维度也相同,他们来自于encoder hidden states. 如果用矩阵表示所有的key的话,行数就是输入序列长度,列数是向量维度。value 矩阵同理。Query来自decoder hidden states,query矩阵的行数可能和key矩阵不同,毕竟输入输出序列的长度不一定相同,但是向量维度是一样的。

img

Query和Key向量会用dot product的方式来计算他们的相似度。每一个Query和所有的Key的相似度都计算完之后,用softmax来计算一个分布,其实也就是Alignment Scores。然后每个value按位乘上自己对应的score再相加,得到输入decoder的memory。用矩阵表示为: \(\operatorname{softmax}\left(Q K^{T}\right) V\)

1.4. Setup for Machine Translation

  1. word2vec一下,vectorize每个token。
  2. 定义好句子的起止符号,和占位符(句子长度小于模型容纳长度时候用的)。

1.5. Training

Teacher Forcing:

在decoder中,它每次不使用上一个state的输出作为下一个state的输入,而是直接使用训练数据的标准答案(ground truth)的对应上一项作为下一个state的输入。Teacher Forcing能够使训练收敛更快更准确,不让错误积累。但是Teacher Forcing也有一个问题,就是在模型预测的时候,我们还是会用上一个state的输出作为下一个state的输入,所以这和在训练过程中有很大不同,模型就会变得脆弱。

NMT的训练过程和实现细节我们可以用下图概况。

img

  1. 0表示输入tokens,1表示目标tokens,Select([0,1,0,1])表示输入输出各复制一份。
  2. 从左边开始看起,一份输入,首先会embedding向量化,然后进入encoder的LSTM,每一个向量化的token进入一个LSTM cell去计算key和value(就是hidden state 输出,这里key和value是一样的)。
  3. 然后就是一份target,和上面那一份输入有点不同的是,这份target先会执行一个ShiftRight的操作。这个操作就是按位向右移动而已,比如说第二个target就是第三个输出位置的输入。显然,这一操作是为了实现teacher forcing。完事了之后,和上面无异了,embedding+LSTM,计算Query向量。
  4. 另一份输入token传上去到Fn层,我的理解是为了做masking,从输入里面知道哪些位置是需要mask的。Masking很简单,就是把输入序列里面的占位符的向量全都改成 -1 billion。这样做点积的结果非常非常小,softmax的概率也会为0。
  5. 另一份target token会传到输出那边做ground truth和prediction做比较。
  6. 然后呢,QKV就会做attention操作,residual的作用是,把query向量和对应的attention的结果相加。这个结果会做activation然后接着往下走。
  7. 然后到了图的右上角,这里我们会用select来drop掉mask向量,因为没啥用了。然后,activation会往下走,输入LSTM,然后每个cell的输出过dense层再做softmax求概率,而target token就会往右做ground truth的角色。

1.6. Evaluation

  1. BLEU score
  2. ROUGE score

2个都差不多,基于N元语法数数,需要的时候再了解。

1.7. Sampling and Decoding

  1. Random Sampling,根据softmax的概率分布来抽样。这样太随机了。

  2. Temperature in Sampling,Random Sampling的升级版,用temperature这个超参数来控制随机的程度,增大高概率的词的出现概率,减少低概率的词的出现概率。temperature取值范围0到1,越大越随机,越小越确定。

  3. Greedy Decoding,每一步选择最大概率的词作为输出。对长序列不好。

  4. Beam Search,每一步生成多个候选(这是一个超参数,beam size)的输出序列,并在此候选序列的基础上探索下一步的序列。其实就是条件概率。看看下面的例子:

    假设字典为[a,b,c],beam size选择2,则:

    1. 在生成第1个词的时候,选择概率最大的2个词,(假设)那么当前序列就是a或b。
    2. 生成第2个词的时候,我们将当前序列a或b,分别与字典中的所有词进行组合,得到新的6个序列aa ab ac ba bb bc,然后从其中选择2个概率最高的,作为当前序列,(假设)即ab或bb。
    3. 不断重复这个过程,直到遇到结束符为止。最终输出2个概率最高的序列。

    通过这种启发式搜索(heuristic search),可减小模型学习阶段performance与测试阶段performance的差异。

  5. Minimum Bayes’ risk (MBR)

    1. 生成几个随机抽样decoding samples
    2. 两两比较similarity,比如说用ROUGE score。
    3. 选择有最高average similarity的sample

2. Transformers

这里我们将以Text Summarization做例子。

2.1. Transformers VS RNNs

RNN有一个很大的问题就识不能并行化,这会导致模型训练和预测都很耗时。序列越长,模型处理的时间越长。此外,RNN还有vanishing gradient的问题。还有一个问题之前在Seq2Seq模型也讲过,就是信息丢失的问题。

Transformer 最牛逼的地方是,用multi-head attention来替代RNN。那么Transformer怎么在没有RNN的情况下去解决输出序列的顺序问题呢?答案是positional encoding.

要了解什么是multi-head attention,我们先看看self-attention。简单来说,看下图,self-attention就是,对输入编码器的每个词向量,都创建 3 个向量,分别是:Query 向量,Key 向量,Value 向量。这 3 个向量是词向量分别和 3 个矩阵相乘得到的,而这些矩阵是我们要学习的参数。从实现的角度来看,其实每个矩阵就是一个dense层(全连接层)。

image-20201229224147261

知道啥是self-attention之后,我们可以看看下图对multi-head attention有个大致的了解。然后再接下来的章节再细细道来。

image-20201229224540250

2.2. Transformer Applications

image-20201229225503512

2.3. Dot-Product Attention

一图解释所有:Q表示query向量集合,K表示key向量集合,V表示value向量集合。

image-20201229230216519

其中Q矩阵的行数是target sequence的长度,列数是每个向量的大小。K和V矩阵的行数是输入序列的长度,列数是向量大小,和query向量的大小相同。$\operatorname{softmax}\left(Q K^{\top}\right)$算出来的矩阵,我们一行行看,其实就是每个query的对应的输入序列的每个词的attention scores的分布。然后再乘以V矩阵,我们得到的矩阵Z其实就是,每一个query对应的输入序列的weighted average value向量。也就是,输入序列的每个词的value向量的所有维度乘以对应的attention score,然后相加。

2.4. Causal Attention

三种attention的方式:

  1. Encoder-Decoder attention: one sentence (decoder) looks at another one (encoder)
  2. Causal (self) attention: In one sentence, words look at previous words, 主要用在句子生成的场景,很简单的道理,句子生成的时候是一个个生成的,将来的词都没生成,所以不能pay attention to。
  3. Bi-directional self attention: In one sentence, words look at both previous and future words, Bert和T5用的是这个

关于Causal attention的实现其实也是十分清楚明确,看下图,就是在softmax之前,加一个M矩阵就可以了。

image-20201230121328665

2.5. Multi-head Attention

2.6. Transformer Decoder

2.7. Transformer Summarizer

其他

这一part主要是后来看了一些资料加深对模型细节的了解,暂时只做描述,不做归类

  1. dense矩阵的共享理解

    其实从下图可以看得出来,Q, K, V的参数矩阵应该是所有输入词向量共享的。

    image-20210109135704803

  2. 关于self-attention,其实就是输入词向量矩阵copy三份(有时两份,如果K,V一样的话),分别过dense layer(等同于乘以上面的系数矩阵),求得QKV。然后做attention操作,$\operatorname{softmax}\left(Q K^{T}\right) V$,记得attention层的输出就是加权的V。

  3. multi-head attention本质上是self-attention,不同的是输入会进行多次self-attention,然后就得到多个加权的V了吗,然后把它们都concat起来,我们把结果叫Z吧,Z的维度最后会和X一样。

  4. 输入序列其实可以直接表示为矩阵的理解,这个和LSTM-based的encoder不一样了吧,在transformer里面,输入序列其实就是用矩阵表示就好了,如上图X。

  5. encoder和decoder的区别

    先看原图:

    Image

    再看细节图:

    Image

    区别注意是2方面:

    • Decoder的第一层是Masked Multi-head Attention,也就是causal attention,注意这一层也是multi-head,所以最后输出的话,维度和输入向量是一样的

    • 然后呢上面的输出回进入到Decoder独有的一层,Encoder-Decoder attention,这个就是之前介绍的3种attention方式之一(Q来自decoder,KV来自encoder)。这个KV来自encoder是为啥呢,encoder这边,输入经过了multi-head attention之后又回到了原本词向量的大小,我的理解是呢,这时候,这个attention之后的词向量回再经过fead -forward(KV当成相同就好了),生成KV向量传递到decoder。而来自decoder的Masked Multi-head Attention的向量呢,就直接作为Q向量。这些QKV的向量都是和输入向量维度是一致的我觉得。

  6. 关于decoder的输入,就是traget shift right。其实把它理解我一个个输入是最好理解的,但是呢,我们采用的是teacher forcing,其实等价于直接矩阵式全部输入。在测试的时候就不行了,要一个个来。

  7. decoder序列输出的理解,这个就是也没啥说的,训练的时候就是矩阵进矩阵出。测试的时候就一个个进一个个出,直到EOS。虽然看起来两种形式,但是模型参数格式是通用的,想想就知道了。

  8. gpt - only decoder的结构理解。其实不用纠结于decoder的这个说法,感觉这么说也只是因为gpt用了masked multi self attention而已。输入的是大段文字序列,然后定义了一个window content size k,用前k个词去预测当前词。所以self attention只在前k个词那里做,屏蔽了其他位置的。细想一下,其实和典型的transformer的decoder输入和mask-sefl-attention的处理是一样的。

    可以想想gpt为啥不用encoder-decoder的结构呢,我觉得是他们建模的任务不同,transformer原本是对翻译建模,而gpt是对LM建模,所以有decoder就够了。GPT下游的话应该只能做分类的任务。

  9. bert - only encoder的结构理解。bert的话,如果对Masked LM建模,encoder那边输入应该是masked 的sequence。用encoder已经可以表达了。如果对NSP建模,encoder也一样可以。反正,目前看来,只要不涉及到masked self-attention, 其实都可以用encoder来表达。bert的输出应该也是要维护整个序列的,不是只输出选中的masked或者replaced的词。只有这样,bert设计的那个mask和replace的策略才有意义,能够维护每个输出位置的向量。

  10. 对pre-training的一些理解:之前理解得有些狭隘其实,以为所有都是生成了word embedding(word2vec, elmo仍然是),现在才知道向GPT,bert原来是train一个较general的模型,然后在下游各种任务中fine tunning。当然啦,把gpt和bert输出当成embedding也是可以的,然后另外加功能层去实现自己想要的功能。比如说Bert+LSTM+CRF。

  11. positional embedding的理解。其实现在想来,所有pre-train的模型,以及transformer,他们的输入,其实已经是word embedding了,当然啦,经过这些模型的加工,可以成为新的embedding。然后,positional embedding呢,是在模型输入之前,就已经加上embedding那里了,为了让位置的信息能够被考虑。包括BERT的segment embedding,其实是同样的道理。反正,这些位置信息,顺序信息,总归是一个信息,肯定有啥用,所以先考虑进去就对了,丢了反正很可惜。综上,positional embedding并不是像我之前想的那样,决定输出的顺序。

Reference

  1. deeplearning.ai 的专题课程 Natural Language Processing Specialization 第四课。
  2. 图解Transformer:https://mp.weixin.qq.com/s/oGf01yf1eG7zvc1oMPEl0g