Transformer in pytorch
一 Transformer overview 本文结合pytorch源码以尽可能简洁的方式把Transformer的工作流程讲解以及原理讲解清楚。全文分为三个部分 Transformer架构:这个模块的详细说明 pytorch中Transformer的api解读 实际运用:虽然Transformer的api使用大大简化了打码量,但是还有需要自已实现一些代码的 Transformer架构 Transformer结构如下:  Transformer的经典应用场景就是机器翻译。 整体分为Encoder、Decoder两大部分,具体实现细分为六块。 输入编码、位置编码 Encoder、Decoder都需要将输入字符进行编码送入网络训练。 Input Embeding:将一个字符(或者汉字)进行编码,比如“我爱中国”四个汉字编码后会变成(4,d_model)的矩阵,Transformer中d_model等于512,那么输入就变成(4,512)的矩阵,为了方便叙述,后面都用(4,512)来当成模型的输入。 positional encoding:在Q、K、V的计算过程中,输入单词的位置信息会丢失掉。所以需要额外用一个位置编码来表示输入单词的顺序。编码公式如下 $PE_{pos,2i}=sin(pos/1000^{2i/d_{model}})$ $PE_{pos,2i+1}=cos(pos/1000^{2i/d_{model}})$ 其中,pos:表示第几个单词,2i,2i+1表示Input Embeding编码维度(512)的偶数位、奇数位。 论文中作者也试过将positional encoding变成可以学习的,但是发现效果差不多;而且使用硬位置编码就不用考虑在推断环节中句子的实际长度超过训练环节中使用的位置编码长度的问题;为什么使用sin、cos呢?可以有效的考虑句中单词的相对位置信息 多头注意力机制(Multi-Head Attention) 多头注意力机制是Transformer的核心,属于Self-Attention(自注意力)。注意只要是可以注意到自身特征的注意力机制就叫Self-Attention,并不是只有Transformer有。 示意图如下  Multi-Head Attention的输入的Q、K、V就是输入的(4,512)维矩阵,Q=K=V。然后用全连接层对Q、K、V做一个变换,多头就是指的这里将输入映射到多个空间。公式描述如下: $MultiHead(Q,K,V)=Concat(head_1, head_2,…, head_n)W^o$ 其中 $head_i=Attention(QW^Q_i, KW^K_i, VW^V_i)$ 其中 $Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V$ 其中$W^Q_i\in R^{d_{model}*d_k}, W^K_i\in R^{d_{model}*d_k}, W^V_i\in R^{d_{model}d_v}, W^o\in R^{hd_vd_{model}}$, 论文中h=8, $d_k=d_v=d_{model}/h=512/8=64$ $QK^T$称为注意力矩阵(attention),表示两个句子中的任意两个单词的相关性。所以attention mask不一定是方阵。 前向传播模块 Q、K、V经过Multi-Head Attention模块再加上一个残差跳链,维度不变,输入维度是(4,512),输出维度还是(4,512),只不过输出的矩阵的每一行已经融合了其他行的信息(根据attention mask)。 这里前向传播模块是一个两层的全连接。公式如下: $FFN(x)=max(0, xW_1+b_1)W_2+b_2$, 其中输入输出维度为$d_model=512$, 中间维度$d_{ff}=2048$ 带Mask的多头注意力机制 这里的Mask Multi-head Attention与步骤2中的稍有不同。“我爱中国”的英文翻译为“I love china”。 在翻译到“love”的时候,其实我们是不知道“china”的这个单词的,所以在训练的时候,就需要来模拟这个过程。即用一个mask来遮住后面信息。这个mask在实际实现中是一个三角矩阵(主对角线及下方为0,上方为-inf), 定义为$attention_mask$大概就长下面这个样子 !...