Transformer
前言
在之前,已经学习了word2vec、RNN网络,简单了解了LSTM等,现在使用更广泛的是基于Transformer的网络模型。
Transformer做的是什么?
答:用于替代RNN,解决使用一堆RNN时存在的问题
更具体的,在了解Transformer做的是什么之前,需要知道的是在NLP中的机器翻译模型中常见的Seq2Seq网络,也即所谓的编码器+解码器整合的结构,如图中对应的输入是一种语言如中文,输出是另一种语言如英文。
中间的模型原来都是放一堆RNN就可以了,既然RNN就可以了,还要提出Transformer干什么呢?
RNN存在的问题
RNN的结构如下图,其后面的输出部分依赖于前面,因此无法做到并行计算,RNN不容易并行计算,但CNN可以啊,为什么不用CNN去替代而是提出使用一种新的Transformer呢?

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

Self-Attention
为了解决上述RNN和CNN在并行计算和长序列计算中存在的问题,有人提出了使用Self-Attention来取代之前的RNN。
Attention,一言以蔽之就是注意力机制,顾名思义,”注意力“就是说对于输入的数据,需要关注的点是什么?就与人观看物体一样,视觉中心会在自己关注的地方,而对其它内容则会相对忽视。而Self-Attention则是表示的针对自己而言,”注意力"所在的地方,例如,人在照镜子时,看镜子中的自己,此时也会有一个关注点,表示其注意力。换到具体的自然语言中则是表示连续序列中,不同的词对于其它词的关注情况,如The dog didn't go because it was too tired.这句话中,it
与The 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表示的是残差连接,和残差网络中的残差连接一样,也就是说将数据处理后的结果加到原来的输入上,保证了原始数据的存在