赞
踩
RNN
一般被用来处理序列输入的,但是它有一个缺点就是不能并行化,后面一个神经元的输入要依赖与之前神经元的输出。
然后就有人提出了
CNN
来取代RNN,关于CNN的详解可以看这篇博客:CNN
CNN用filter
来处理序列,引入多个filter,可以并行处理,但是一个filter只能作用于一段区间的序列,如果想作用较长的区间,就要叠加多个CNN
比如下图黄色三角形的是通过一个filter,作用于sequence的三个输入,叠加一层蓝色的filter,作用也是三个sequence(这时是第一个filter的输出,b1,b2,b3),这三个词就考虑到了a1-4所有的输入)
为了解决并行和一次考虑全部输入的问题,
Transformer
诞生了!!!
Transformer引入了自注意力机制,使每一层神经元的输出都考虑到该层的全部输入,并且可以并行化计算每一个神经元。
关于自注意力机制的Q、K、V的详细解释,大家可以参考这篇博客:如何理解自注意力机制中的Q、K、V
self-attention
输入是整个序列,输入也是一个序列,并且和输入序列相同,每一个输出向量都要考虑到全部输入序列的信息,所以self-attention引入了三个矩阵Q(query)
、K(key)
、V(value)
。
①首先,对于每一个输入,都要计算Q、K、V
三个矩阵的计算方式是:
对于每一个输入向量,分别乘上三个不同的权值矩阵
计算完每一个输入,都会得到三个矩阵Q、K、V
②下一步就是拿每一个query q去对每一个key k 做 attention
先用q1来对k1,k2,k3,k4做attention,分别得到
α11、α12、α13、α14
,得到的这几个αij
表示输入向量i对j的注意力分数,分数越大,影响也就越大。
计算的公式一般如下:
计算一个q之后的结果如下:
Q:为什么除以一个根号d
A:dk是K的维度,除以一个根号d因为Q和K相乘之后的维度可能会很大,除以根号d可以平衡维度
③再下一步是将上一步计算的αij做一个softmax
,
softmax的计算如下:
这一步计算后的结果如下:
④最后一步,就是得到这一层的输入,对于x1,我们得到输出b1
用上一步得到的
α帽
乘上第一步计算出的每一个输入的V
,再将这些值这个值相加,就得到了第一个输入的 输出b1,计算公式如下:
计算后的结果如下:
因为attention的输出也是一个序列,现在计算出了序列的第一个vector->b1,这个b1考虑了整个输入序列,所以self-attention可以看到整个序列!然后也可以同时计算出b2,b3,b4,方式是一样的,并且他们可以并行处理。
所以最后的结果就是:
通过输入x1,x2,x3,x4,我们得到了b1,b2,b3,b4,并且这四个输出bi是可以并行计算的,他们考虑了整个输入序列
①计算K、Q、V的值, 在计算K、Q、V的时候,所有的输入(α1,α2,α3,α4)都分别乘上Wq,Wk,Wv,最后得到(q1,q2,q3,q4)(k1,k2,k3,k4)(v1,v2,v3,v4)
那么我们可以考虑把所有的输入合起来作为一个矩阵,每一列是一个输入向量,最后乘上Wq,Wk,Wv得到的也是矩阵:
如下图所示
②计算attention,上一步计算出每一个输入的K、Q、V之后,我们可以用每一个输入的q去乘上每一个输入的k来得到α
拿q1来说,第一个计算就是拿q1
乘上(k1,k2,k3,k4)
得到(α1,α2,α3,α4)
所以我们可以将所有的k作为一个矩阵,每一行是一个输入的ki
对于q1是如此,对应q2,q3,q4也是这么计算的,那么我们可以把q也作为一个矩阵,每一列表示一个qi
所以attention的计算就变成了矩阵乘法,用K矩阵在转置乘上Q矩阵得到attention分数
③计算attention的softmax
然后attention再做一个softmax得到最后的分数。
④计算输出b,上一步得到的attention矩阵,其实每一列就是每一个输入对其他输入的attention分数,当计算bi
的是,我们用的是第i
个输入对其他的输入的的attention,也就是αij
,j是从1到4,分别乘上对应输入的vj
,求和。
所以我们可以把v看做一个矩阵,每一列对应一个输入的vj,矩阵v是(1X4),矩阵α是(4X4),所以b就是(1X4),也就对应四个输出(b1,b2,b3,b4)
最后,self-attention的输入是矩阵
I
,输出是矩阵O
完整的计算过程如下图所示,所以self-attention做的就是一堆矩阵乘法,用GPU可以加速
多头注意力机制,就是对每一个计算出来的Q、K、V
,再根据头的多少去乘上不同的矩阵,得到更多的q,k,v
,但是在计算的时候,每一个q之和对应位置的k、v做计算
比如qi,1
只和ki1,kj,1
做计算再和vi,1
,vi,2
做计算,得到bi,1
,同样的方式可以得到bi,2
,bi=bi,1+bi,2
Q:为什么用多头注意力?
A:因为每一个头可能关注的点是不一样的
前面的self-attention忽略了一个信息,就是每一个vector的位置信息,这样就导致对于每一个输入,在计算注意力分数的时候,无论多远的邻居对它来说都是一样的。
如上图所示,对于每一个输入ai,都加上一个位置信息ei,i表示的是vector的位置,每一个vector都对应一个唯一的ei,这个ei可以人工设定,也可以通过一个model得到,然后ai+ei
再进行后续的计算就可以了
一般来说,Seq2Seq模型会有一个Encoder,一个Decoder,输入一个序列,输出一个序列,最常用在机器翻译。
以前的Encoder和Decoder内都是用RNN模块来做,但现在,可以用self-attention来取代RNN。
整个Transformer是一个基于多头自注意力机制的seq2seq模型,整个模型可以分为Encoder
和Decoder
两个部分
一个看到麻木的模型图~
左边就是Encoder,右边就是Decoder,这个seq2seq模型输出序列的长度是不确定的。输入一个sequence后,先由Encoder负责处理,再把处理好的结果输入到Decoder中,由Decoder决定最后输出什么样的sequence
对于之前seq2seq模型,中间模块为RNN,CNN等,现在换成了如上图左边的内容,多头自注意力机制
对于输入,得到它的embedding之后,加上位置编码Positional Encoder输入到Encoder,黑色框内的部分可以重复N次,这个block要做的事情是,先经过一个Multi-haed Attention和一个Add&Norm,在经过一个Feed Forward和一个Add&Norm
Multi-haed Attention
就不用多说了,如下图所示
Add
Add表示的是,对于Multi-haed Attention的每一个输出bi,要加上它的输入a作为最终的输出,即b’=a+b
Norm
是一个Norm Layer层,层归一化(Layer Normalization)是对一个中间层的所有神经元进行归一化,关于均值和方差的求导可以参考如下公式(我是从顾道长生’博主那截取的~):
Feed Forward
,这一层是一个全连接层的前向传播计算。
1.在将输入向量进行self-attention之前,先加上Positional Encoding,也就是输入向量中的位置信息。
2.Multi-Head Attention:进行Multi-Head的self-attention处理得到输出向量。
3.Add & Norm (residual & layer normalization): 也就是将self-attention的输出加上它对应的输入然后对其进行Layer Normalization。
4.Feed Forward:将上一层的输出输入到fully connected Network中,将得到的输出向量和对应的输入向量同样经过residual & layer normalization操作后得到该block的最终输出。
5.将这个block重复n次
在Decoder部分,有一个地方Encoder没有的就是Mask部分,这个Mask是希望attention专注于已产生的序列部分。
参考文献
博客:(2021李宏毅)机器学习-Transformer
视频:李宏毅2020机器学习深度学习
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。