赞
踩
Transformer除了本身是一个重要的深度学习模型外,内部的一些实现细节(尤其是self-attention)也经常会使用到,为了防止遗忘,这里对Transformer的实现做一个详细的记录。
(内容是对李宏毅老师课程的记录)
在RNN类的网络中(SimpleRNN,LSTM,GRU等),有一个很明显的缺点在于该网络无法实现并行化,因为下一步时间步的输入依赖于上一个时间步的输出。而transformer可以很好的解决这一个问题,做到并行化。在讲transformer之前,我们也可以用CNN来实现并行化,如下图所示:
CNN可以自由选择窗口的大小,来决定要考虑多少个上下文词,第一层的CNN无法考虑整个序列的信息,但是更高层的CNN可以,比如上图右侧中蓝色的三角形,编码了三个黄色方块的信息,从而间接了考虑了更多的token信息。
如果将Self-Attention看成是一个黑盒的机制,那么它跟RNN一样,对每一个token都生成一个向量的输出。不同点在于,b1, b2, b3, b4是同时被计算出来的。
我们以输入x1到输出b1的过程来举例:
首先,将序列中的每个token转换为向量表示(bert, word2vec, glove等),然后每个输入向量会乘以对应的matrix,转换成q1, k1, v1三个向量,以第一个位置a1举例:
首先,由输入层(词向量那一层)到q,k,v的过程中,是完全可以并行化的,如上图所示:
q乘以k的过程也可以矩阵化,比如点积运算,我们可以将k矩阵做转置,和q进行一个矩阵乘法,这样得到的是1*1的矩阵,也就是一个数值。
同理, 多个q也是如此,softmax的过程也可以对矩阵做softmax,指定正确的axis即可。
得到最终输出的过程也可以用矩阵表示,如上图所示。
整个过程如上图所示。
Multi-head Self-attention的思想在于:对得到的q再乘以不同的权重得到多组新的q,然后q只对和它在相同位置的k做运算,比如第一个head中的q只会对序列中其他位置的第一个head中的k做运算。此时,有N个head,我们就会得到N个vector,可以将他们concat起来。
如果对concat得到的形状不满意的话,可以对其做一个线性变换,将其转为想要的维度。
由于self-attention在计算的时候,没有考虑位置信息。在原始的论文中,对输入ai加上了一个位置向量ei,这个位置向量不是通过训练得到的,是直接加上去的,当然也可以用训练的方式,但是效果好像不会更好。
对于ei的产生的过程,我们可以这样想象,我们在原始的xi中append一个one-hot的向量,然后通过乘以权重矩阵的方式,得到ei,得到ei权重矩阵wp,画出来的话长如下这个样子:
我们经常会用的是batch_normalization,做batch_normalization的目的是让同一个batch内,不同样本同一纬度的feature的mean为0,variance为1。
而layer_normalization不需要考虑batch,它是让同一个样本不同维度的均值为0,方差为1。layer_normalization一般搭配RNN使用,这也是transformer用layer_normalization的理由。
其中有个Add需要注意,Add的操作是将多头注意力机制的输入和输出拼接在一块,然后做一个线性变换到指定的维度,类似于残差连接的思想。Normal即layer_normalization。
右半部分是Decoder部分,其中的Masked Multi-Head Attention只会attend已经产生的token,然后在后续的一个Masked Multi-Head Attention层,将Encoder的输出作为输入的一部分,其余的部分都是类似的了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。