结构由encoder和decoder构成。
1.1 encoder
由N=6个相同的layer组成,每个layer如上图左侧单元所示。
每个layer由两个sub-layer组成,分别是Multi-Head self-Attention机制和fully connected feed-forward network.其中每个sub-layer都加了residual connection和normalisation,因此可以将sub-layer的输出表示为:
接下来按顺序解释一下这两个sub-layer:
- Multi-head self-attention
Attention函数的本质可以被描述为一个查询(query)与一系列(键key-值value)对一起映射成一个输出。分为以下3步:
- 将query和每个key进行相似度计算得到权重,常用的相似度函数有点积,拼接,感知机等
- 使用一个softmax(因为是一系列的k/v,所以类似多分类,要用softmax)函数对这些权重进行归一化
- 将权重和相应的键值value进行加权求和得到最后的Attention。
公式如下:
目前在NLP研究中,key和value常常都是同一个,即 key=value(如下例中的源语言的编码器输出)。
- 机器翻译里的源语言的编码器输出
hjhj
就是V
- 机器翻译里的源语言的编码器输出
hjhj
同样是K
- 机器翻译里的目标语言的隐层状态
zizi
就是Q
https://daiwk.github.io/posts/nlp-self-attention-models.html
也就是说多头指的是:在基础Attention的基础上,变换Q,K,V的系数再求Attention,求多次并将其拼接起来,就得到多头。self-Attention是指取Q,K,V相同。因为是encoder内部自身的求Q,K,V。K,V都是hj,Q是zj,这里zj=hj(如何使在decoder中求注意力,zj是decoder的隐藏层状态)。
- Position-wise feed-forward networks
这层主要是提供非线性变换。Attention输出的维度是[bsz*seq_len, num_heads*head_size],第二个sub-layer是个全连接层,之所以是position-wise是因为过线性层时每个位置i的变换参数是一样的。
1.2 decoder
Decoder和Encoder的结构差不多,但是多了一个attention的sub-layer,这里先明确一下decoder的输入输出和解码过程:
输出:对应i位置的输出词的概率分布
输入:encoder的输出 & 对应i-1位置decoder的输出。所以中间的attention不是self-attention,它的K,V来自encoder,K,V指的是encoder中的hj,Q来自上一位置decoder的输出。
解码:这里要特别注意一下,编码可以并行计算,一次性全部encoding出来,但解码不是一次把所有序列解出来的,而是像rnn一样一个一个解出来的,因为要用上一个位置的输入当作attention的query。
1.3 Positional Encoding
除了主要的Encoder和Decoder,还有数据预处理的部分。Transformer抛弃了RNN,而RNN最大的优点就是在时间序列上对数据的抽象,所以文章中作者提出两种Positional Encoding的方法,将encoding后的数据与embedding数据求和,加入了相对位置信息。