0%

Transformer

Transformer

前言

在之前,已经学习了word2vec、RNN网络,简单了解了LSTM等,现在使用更广泛的是基于Transformer的网络模型。

Transformer做的是什么?

答:用于替代RNN,解决使用一堆RNN时存在的问题

更具体的,在了解Transformer做的是什么之前,需要知道的是在NLP中的机器翻译模型中常见的Seq2Seq网络,也即所谓的编码器+解码器整合的结构,如图中对应的输入是一种语言如中文,输出是另一种语言如英文。

中间的模型原来都是放一堆RNN就可以了,既然RNN就可以了,还要提出Transformer干什么呢?

RNN存在的问题

RNN的结构如下图,其后面的输出部分依赖于前面,因此无法做到并行计算,RNN不容易并行计算,但CNN可以啊,为什么不用CNN去替代而是提出使用一种新的Transformer呢?

RNN计算
RNN计算

主要是因为如下图,CNN虽然可以并行计算,但是浅层CNN无法考虑长序列,只有深层的CNN才可以考虑到比较多的序列数据,这就意味着需要叠很多层,参数太多。

CNN计算
CNN计算

Self-Attention

为了解决上述RNN和CNN在并行计算和长序列计算中存在的问题,有人提出了使用Self-Attention来取代之前的RNN。

Attention,一言以蔽之就是注意力机制,顾名思义,”注意力“就是说对于输入的数据,需要关注的点是什么?就与人观看物体一样,视觉中心会在自己关注的地方,而对其它内容则会相对忽视。而Self-Attention则是表示的针对自己而言,”注意力"所在的地方,例如,人在照镜子时,看镜子中的自己,此时也会有一个关注点,表示其注意力。换到具体的自然语言中则是表示连续序列中,不同的词对于其它词的关注情况,如The dog didn't go because it was too tired.这句话中,itThe dot之间的互相关注的程度就会相对比与其它词如was等词要大的多。

一句话简单概述就是:有一种新的模型层叫Self-Attention,它的输入的输出和RNN是一样的,但是它可以并行计算出输出结果

Self-Attention的总体结构如图,输入输出和RNN是一样的:

Self-Attention的内部

Self-Attention的计算过程

如图,对于输入\(x^1\sim x^4\),通过词嵌入编码将文本转换成对应的词向量\(a^1\sim a^4\),然后输入到Self-Attention层,Self-Attention层进行的计算:

对于每个输入\(a^i\),分别乘以三个权重\(W^q、W^k、W^v\)变换得到三个向量\(q^i,k^i,v^i\)

计算公式如下: \[ q^i = W^qa^i \\ k^i = W^ka^i \\ v^i = W^ka^i \]

其中:

\(q\):意思是query,表示用于查询其它的词

\(k\):意思是key,表示用于等待被其它的q查询的

\(v\):意思是value,表示实际的特征信息

如图,计算出了\(q^i,k^i,v^i\)后,就需要进行attention计算了,计算过程:

使用每个\(q^i\)去对每个\(k^i\)进行attention计算,计算公式为: \[ a_{i,j} = \frac{q^i\cdot k^j}{\sqrt{d}} (图中表示的i=1的情况) \]

注:这里为什么需要除以\(\sqrt{d}\)呢?(d表示\(q\)\(k\)的维度)

主要是因为\(q\)\(k\)的内积的数值会随它们的维度越来越大,导致其方差也会过大,因此通过除以d来维平衡

如图,对于上一步的\(a_{i,j}\)进行softmax计算,即将每个\(a_{i,j}\)取e次幂,再除以所有\(exp(a_{i,j})\)的和,公式如下: \[ \hat a_{i,j} = \frac{exp(a_{i,j})}{\sum_k exp(a_{i,k})}(图中表示的i=1的情况) \]

如图,将得到的\(\hat a_{i,j}\)与每个\(v^{i}\)相乘再求和,得到的结果就是最终输出\(b^{i}\)了,公式如下: \[ b^i = \sum_{j}\hat a_{i,j}v^{j} (图中表示的i=1的情况) \]

Self-Attention计算的矩阵表示

如图,在实际应用中,通常会采用矩阵计算来加快计算速度,因此,对符号进行以下说明: $$

Q:表示q组成的矩阵 \ K:表示k组成的矩阵 \ V:表示v组成的矩阵 \ W^q:表示生成q的权重矩阵 \ W^k:表示生成k的权重矩阵 \ W^v:表示生成v的权重矩阵 \ I:表示输入转换后的词向量矩阵,对应之前的a \ $$

如图,在注意力计算时,符号如下: \[ A:表示k与q注意力计算即内积后的值 \hfill \\ \hat A:表示a_{i,j}经过softmax后的\hat a_{i,j} \hfill \\ 计算公式:A = K^TQ \hfill \]

如图是求最终输出的过程,符号表示如下: \[ V:表示由v构成的矩阵 \hfill \\ O:表示最终输出b构成的矩阵 \hfill \\ 计算公式:O=V\hat A \hfill \]

注:类似的,将a生成q,k,v时,如果生成多组q,k,v,然后再将得到的多个特征(输出O)拼接在一起,最后还可以选择通过一层全连接层来降维,这样一来就是所谓的多头注意力机制了,

Transformer的整体架构

如图,Transformer主要包括了位置编码、编码器、解码器

位置编码

由Self-Attention计算的过程可以发现,Self-Attention中每个词都会考虑整个序列的加权,因此其出现位置并不会对结果有什么影响,但这样就与实际不符了,因为我们使用Self-Attention处理的就是文本序列等数据,位置信息对其应该产生影响的,因此,这里就通过位置编码对数据进行了处理。

具体的处理过程如下:

假设输入转换后的词向量为\(x_i\),对应的位置编码为\(t_i\),则得到的新的具有位置(或时间)信息的词向量为\(x'_i=x_i+t_i\)

而这里的\(t_i\)是如何计算的呢?

方法有很多,Transformer通常采用的方法是使用周期性函数进行变换,公式如下: \[ PE_{(pos, 2i)} = \sin (pos/10000^{2i/d_{model})}) \hfill \\ PE_{(pos,2i+1)} = \cos (pos/10000^{2i/d_model}) \hfill \]

编码器

如图,编码器主要由注意力层、前向反馈层构成,对于输出的单词,先经过编码处理得到词向量\(x_i\),如图中的\(x_1,x_2\),然后将词向量输入到注意力层,得到输出\(z_1,z_2\)\(z_1,z_2\)都是包含\(x_1\)\(x_2\)信息的,只是可能\(z_1\)更关注\(x_1\)\(z_2\)更关注\(x_2\),然后再将\(z_1,z_2\)输入到全连接层,得到一组新的能更好表示信息的向量\(r_1,r_2\)

同样的,这组向量\(r_1,r_2\)也可以作为下一个编码器的输入\(x_1,x_2\),同理进行计算。

解码器

解码器与编码器不同点在于,解码器的Attention的计算不同,并且加入了MASK机制,其后面的Attention中的K和V是来自于编码器,而只有Q是来自于原数据计算,而MASK机制则是将输入进行掩码处理,这里的输入在训练时指的是将真实值作为输入,因此需要进行MASK,而在测试过程中,则是使用上一时间步生成的结果作为输入

一些其它的处理

Normalize

这里的归一化用的不是常见的Batch Normalization,而是Layer Normalization

  • Batch Normalization

    如图,竖着的红框表示BN,BN是对Batch中的每个数据每个特征按照Batch这一维度使其均值为0,方差为1

  • Layer Normalization

    横着的红框表示LN,LN是对每个数据的每个特征在其数据这一维度下保持均值为0,方差为1

Add

Add表示的是残差连接,和残差网络中的残差连接一样,也就是说将数据处理后的结果加到原来的输入上,保证了原始数据的存在

需要知道的几个问题

输入如何编码?

输出结果是什么?

Attention的目的?

如何组合在一起?