68 Transformer【动手学深度学习v2】

P1。
Transformer虽然也是基于Encoder-Decoder的架构去处理一个序列对(比如一句英语和一句法语)。
但Transformer模型完全基于注意力机制,没有任何RNN,这是与使用attention的seq2seq(用到了RNN)架构不同的地方。
Transformer相当于老瓶装新酒,都是把Encoder最后一层的输出作为Decoder 的输入之一,进行信息的传递。
(6) 第1个子层:深蓝色的多头(自)注意力机制,即Multi-head(-self-) Attention。
对于同一个k、v、q,有的注意力层能抽取长一点的信息,有的注意力层能抽取短一点的信息。所以为了抽取多个特征,需要多个注意力层,即多头注意力(Multi-Head Attention)。
多头注意力有点类似于CNN的多输出通道(channel)。
05:33多头注意力的具体做法:
① KVQ这三大矩阵,分别经过不同的Attention(可以是self-attention也可以不是):进入每个Attention,都会分配好不同的权重矩阵作为FC(全连接层,一般会降维成更低的dimension),比如第i个Attention会分配Wi_q ,Wi_k,Wi_v,。
② 然后将所有的Attention的输出,在特征维度(最后一个维度), concat起来,
③ 最后经过一个FC,使得输出的维度能够符合要求。
07:29 从数学角度解释多头注意力:
① q,k,v向量的长度分别为d_q, d_k,d_v
② 第i个head的可学参数(权重矩阵为主):Wi_q ,Wi_k,Wi_v,shape分别为(p_q,d_q), (p_k,d_k), (p_v, d_v)。
③ 第i个head的输出h_i = f(Wi_q*q, Wi_k*k, Wi_v * v), 长度为p_v
④ 输出(concat之后,最后一个layer的FC)的科学参数W_o 的shape为(p_o, h*p_v),因为有h个head,所以h个head的输出在特征维度concat之后长度为h*p_v
⑤ Muti-Head的输出为W_o * [h_1,h_2,….h_h]^T,长度为p_o
⑥ 注意:p_q,p_k,p_v一般<d_q,d_k,d_v,相当于W对qkv做了降维。
说到多头注意力,这里可以看到Decoder部分还额外多了一个Masked multi-head attention,即带掩码的多头注意力机制。
2. Decoder
(1) Masked multi-head attention
在解码器自注意力中,查询、键和值都来自上一个解码器层的输出。但是,解码器中的每个位置只能考虑该位置之前的所有位置,不能考虑该位置本身和之后的所有位置。这种掩蔽(masked)注意力保留了自回归(auto-regressive)属性,确保预测仅依赖于已生成的输出词元。
这种masked multi-head attention,与注意力评分函数文件attention-scoring-functions.ipynb中的 softmax operation是不同的——前者是不能数据透视用到未来函数,后者是在softmax的计算中,对padding的0值不予考虑,只考虑valid_len以内的元素进行考虑。
回到Encoder。之前插入的Decoder有3个子层,Encoder有2个子层,相比Decoder,在2个子层之间少了1个Masked multi-head attention。
1. Encoder
(7) 第2个子层:浅蓝色的Positionwise FFN,即基于位置的前馈网络。Positionwise FFN对序列中的所有位置的表示进行变换时,使用的是同一个多层感知机(MLP),相当于一个FC(全连接层),这就是称前馈网络是基于位置的(positionwise)的原因。
① 将FFN的input的shape 从(b,n,d)变成(bn,d),即从3维改成2维。
b:多少个句子(样本),n:句子有多少个字(time_step),d:就是这个字是多少维(embedding_size)。
大概因为,FFN的输入,linear函数只能写 input_embed, 和output_embed这两个参数, 所以得切换成二维的形式输入。
因为n是可变的,那n跟batch合并,可以保证ffn的dimension d的一致性。可以理解为ffn处理了 n x batch 这样多个token。
②使用2个FC,将d的长度改成ffn_num_outputs
④ 输出的时候再把(bn,d)变回(b,n,d)
(8) 12:09。 Add&Norm 残差块&层归一化。
①残差块Add:借鉴的是ResNet的思想,这样Transformer块的层数n就可以很深了
②层归一化LayerNorm:与批规范化BatchNorm不同。LayerNorm在每个batch(句子,样本)内部,对n*d的元素做标准化;BatchNorm是在每个d(特征)内部,对batch*n的元素做标准化。因为n(序列长度,time_step)是变化的,所以在样本内部的LayerNorm比BatchNorm更加稳定。
相当于:有b句话,每句话有len(n)个词,每个词由d个特征表示,BN是对所有句子所有词的某一特征做归一化,LN是对某一句话的所有词所有特征做归一化。
2. Decoder
与1.Encoder相比,一开始多了一个子层——Masked multi-head attention。
3. 16:37。Encoder到Decoder的那条线——信息传输。
(1)Encoder最终的输出为y_1,y_2,…,y_n这n个向量,作为context,即Decoder中帝i个Transformer块中的Multi-head的key和value。
(2)这意味着,图中左下角Encoder的Multi-head attention和右下角Decoder的Masked multi-head attention都是self-attention,即QKV都是X矩阵;但是右上角Decoder的Multi-head attention则不是self-attention,此时K和V来自Encoder的输出context(源语言,source),而Q来自目标序列(targets)。
(3) 这意味着Encoder和Decoder的Transformer块的个数n(此n非彼n,彼n为len,即time_step)和输出维度d都是一样的。所以如果有n个Transformer块,就有n条从Encoder到Decoder的信息传输线。
4. 预测。
与训练(model.train())可以并行不同,预测(model.eval())的时候,不能并行。因为它在预测第t+1个输出时,Decoder中输入前t个预测值,如果是在self-attention中,那么前t个预测值作为key和value,第t个预测值还作为query。所以要按顺序预测,类似RNN了,并行度不再是训练时的O(n),而是O(1)。