目录一.transformer整体框架1.自注意力计算1翻译要找联系2初始向量加位置编码 得到词向量3得词向量4得q、k、v5Q 乘 K 再缩放算出注意力分数6softmax 归一化得到词之间的关联权重7权重乘 V 再求和算出自注意力向量Z2.多头自注意力机制Multi-Head Attention8引出多头机制9512 维向量拆成 8 个 64 维的小向量10每组小向量算自注意力拼回 512 维 Z 向量3.编码器二.transformer架构图流程讲解 第一步左侧 Encoder 输入层 第二步左侧 Encoder Block共 N6 层每层结构相同 第三步右侧 Decoder 输入层 第四步右侧 Decoder Block共 N6 层每层结构相同 第五步右侧输出层三.transformer流程详细讲解1.正弦余弦位置编码1单词 Embedding2位置 Embedding正弦余弦位置编码每个参数的解释举例说明以 d4、pos1 为例2.Q, K, V 的计算3.Self-Attention 的输出4.Multi-Head Attention1输入层Q、K、V 向量2拆分多头并行计算注意力Self-Attention3核心计算缩放点积注意力自注意力计算Self-Attention4拼接输出Concat5最终线性变换Linear5.编码器Encoder1Add Norm 残差、归一化2Feed Forward3组成了Encoder一.transformer整体框架1.自注意力计算1翻译要找联系“用毒毒毒蛇毒蛇会不会被毒毒死”若想翻译这句话就要找到这句话每个词之间的联系2初始向量加位置编码 得到词向量这个句子首先会被分词工具分成若干个词每个词对应一个512维的向量这个512维向量还需加法加上一个512维位置编码得到一个新的512维词向量共10组512维新的词向量3得词向量得到10组新的512维新的词向量4得q、k、v用三个权重矩阵分别与每个词向量相乘每个词向量得到q、k、v三个向量Q查询向量当前词想要关注什么?K键向量该词能为其他词提供什么信息?(可看做标签或索引)V该词实际包含的信息内容下面是Scaled Dot-Product Attention缩放点积注意力机制5Q 乘 K 再缩放算出注意力分数MatMulQ × Kᵀ将 Q 与 K 的转置矩阵进行矩阵乘法。Scale缩放将矩阵中的每个元素除以√DₖDₖ是 K 向量的维度用每个词的Q乘每个词的K防止梯度爆炸除上得到注意力分数6softmax归一化得到词之间的关联权重加上softmax把注意力分数保持在0-1之间得到注意力权重这代表每个词的关联程度例如“用”字和第一个“毒”字权重更高和其他“毒”字权重较低7权重乘 V 再求和算出自注意力向量ZMatMul与 V 相乘将注意力权重矩阵与 V 进行矩阵乘法。将注意力权重和每个词的V向量相乘再加权求和得到新的V向量假设叫向量Z这就经过了一次自注意力计算得到了一个向量Z2.多头自注意力机制Multi-Head AttentionMulti-Head Attention8引出多头机制一次自注意力计算得到一个向量Z太少不够用9512 维向量拆成 8 个 64 维的小向量一次自注意力计算太少那么下面是最开始的初始512维向量512维位置编码得到的10组512维词向量直接将10组512维词向量每个向量分成8个64维的向量10每组小向量算自注意力拼回 512 维 Z 向量对应Multi-Head Attention图中的Linear每组8个64维词向量分别进行之前的步骤即计算q、k、v再跑一遍自注意力计算每个64维词向量计算后各自得到一个64维的向量Z然后再将这8个64维的向量Z拼接起来重新得到1个512维向量Z10组的每一组都拼接最终得到10×512的向量Z我们叫它上下文特征矩阵那么这个10×512的向量Z包含了8次独立的自注意力计算这就叫做一层“多头自注意力机制”3.编码器上述的“多头自注意力机制”需要n层并且在每次“多头自注意力机制”后又依次进行 残差网络—归一化—FFNrelu激活—再一次残差网络—再一次归一化最终得到向量X_out。这就形成了编码器主要用途是负责理解输入的语言。二.transformer架构图流程讲解 第一步左侧 Encoder 输入层对应图中模块Inputs输入原始句子→Input Embedding生成词向量→Positional Encoding加入位置编码并执行⊕加法 第二步左侧 Encoder Block共 N6 层每层结构相同对应图中模块Multi-Head Attention多头自注意力层 下面的三个箭头说明需要3个向量q、k、v→Add Norm残差连接侧边箭头 层归一化→Feed Forward两层全连接层→Add Norm→最终输出一个10 × 512的矩阵(向量Z)我们叫它上下文特征矩阵【N 层堆叠这个 Block 会重复 N6 次每一层的输出都是下一层的输入。】 第三步右侧 Decoder 输入层对应图中模块Outputs (shifted right)→Output Embedding生成词向量→⊕→Positional Encoding位置编码输入已生成的英文词翻译是自回归生成的初始输入是START标记后续输入是已经生成的词比如已生成Will下一个输入就是START Will。图中shifted right表示输入是 “右移一位” 的输出序列防止模型偷看未来的词。 第四步右侧 Decoder Block共 N6 层每层结构相同对应图中模块Masked Multi-Head Attention掩码多头自注意力→Add Norm残差、归一化→Multi-Head Attention→Add Norm残差、归一化→Feed Forward→Add Norm最后N 层堆叠第 1 层输出 → 第 2 层输入 → … → 第 6 层输出 → 送入输出层。我们以第 1 层为例Masked Multi-Head Attention掩码多头自注意力输入Decoder 输入层的3 × 512矩阵。计算和 Encoder 的多头自注意力类似但会加入一个上三角掩码让第 i 个词只能关注前 i-1 个词比如生成第 3 个词时只能看前 2 个词防止 “偷看” 未来的词。输出3 × 512的掩码注意力矩阵。Multi-Head Attention交叉注意力交叉注意力Cross-Attention和自注意力Self-Attention模块都是Multi-Head Attention仅仅是输入来源的区别图中看箭头来源解码器上面第二个Multi-Head Attention明显输入来自两个不同的地方显然是交叉注意力。核心区别确实在于查询Q、键K、值V的来源不同。自注意力Q、K、V全部来自同一个句子如输入。交叉注意力Q来自目标句子如翻译结果K、V来自源句子如原文。计算让当前生成的英文词关注输入中文句子里的对应词比如生成poison时会关注中文里的 “毒”。输出3 × 512的交叉注意力矩阵。线的含义Encoder 最终输出 → 作为 K/V 送入该层Decoder 上一步输出 → 作为 Q 送入该层 → 计算交叉注意力 → 输出矩阵。 第五步右侧输出层对应图中模块Linear全连接→Softmax→Output ProbabilitiesLinear 层全连接把 Decoder 输出的 512 维向量映射到整个英文词汇表的大小比如 3 万词。输出3 × 30000的矩阵每个词对应词汇表中所有词的得分。Softmax 层对每个词的得分做归一化得到每个词的概率0~1 之间和为 1。输出3 × 30000的概率矩阵。生成最终词选择概率最大的词作为当前生成的输出比如选择Will。这个词会被送回 Decoder 输入层重复整个流程直到生成END标记翻译完成。最终输出完整的英文句子比如Will a poisonous snake be poisoned if you poison it with poison?。三.transformer流程详细讲解1.正弦余弦位置编码之前所说的最开始每个词对应的初始521维向量和512维位置编码就是Transformer 中单词的输入表示x由单词 Embedding和位置 EmbeddingPositional Encoding相加得到。1单词 Embedding单词的 Embedding 有很多种方式可以获取例如可以采用 Word2Vec、Glove 等算法预训练得到也可以在 Transformer 中训练得到。2位置 Embedding正弦余弦位置编码位置 Embedding 用PE表示PE的维度与单词 Embedding 是一样的。PE 可以通过训练得到也可以使用某种公式计算得到。在 Transformer 中采用了后者计算公式如下这个公式是Transformer 模型中 “位置编码Positional Encoding简称 PE” 的计算方式作用是给句子中的每个单词添加 “位置信息”—— 因为 Transformer 本身没有循环 / 卷积结构无法自动感知单词的顺序所以需要用这个公式生成位置向量和词 Embedding 相加让模型知道单词的先后顺序。每个参数的解释PE(pos, 2i) / PE(pos, 2i1)表示 “位置为pos的单词在位置编码向量的第2i偶数位/2i1奇数位维度上的取值”假设词Embedding维度是6位置编码的维度与词Embedding维度相同则i应该取0、1、2 这样2i涵盖了0、2、4维度2i1就涵盖了1、3、5总共涵盖0、1、2、3、4、5这6个维度。pos单词在句子中的位置序号比如句子 “我有一只猫” 中“我” 的 pos0“有” 的 pos1依此类推。d位置编码的维度就是要把该单词转成几维向量。必须和词 Embedding 的维度相同这样才能相加比如常用的 d512、d768。i维度的索引从 0 开始用来区分偶数 / 奇数维度满足2i ≤ d、2i1 ≤ d。假设词Embedding是6维向量位置编码的维度与词Embedding维度相同则i应该取0、1、2 这样2i涵盖了0、2、4维度2i1就涵盖了1、3、5总共涵盖0、1、2、3、4、5这6个维度。举例说明以 d4、pos1 为例假设位置编码维度d4要计算位置 pos1的单词的位置编码向量当i0时偶数维度2i0PE(1, 0) sin(1 / 10000^(2×0/4)) sin(1/10000^0) sin(1) ≈ 0.8415奇数维度2i11PE(1, 1) cos(1 / 10000^(2×0/4)) cos(1) ≈ 0.5403当i1时偶数维度2i2PE(1, 2) sin(1 / 10000^(2×1/4)) sin(1/10000^0.5) sin(1/100) ≈ 0.0099998奇数维度2i13PE(1, 3) cos(1 / 10000^(2×1/4)) cos(1/100) ≈ 0.99995最终 pos1 的位置编码向量是[0.8415, 0.5403, 0.0099998, 0.99995]之后会和这个位置的词 Embedding维度也是 4相加作为 Transformer 的输入。2.Q, K, V 的计算Self-Attention 的输入用矩阵X进行表示则可以使用线性变阵矩阵WQ,WK,WV计算得到Q,K,V。计算如下图所示注意 X, Q, K, V 的每一行都表示一个单词。3.Self-Attention 的输出得到矩阵 Q, K, V之后就可以计算出 Self-Attention 的输出了计算的公式如下Self-Attention 的输出公式中计算矩阵Q和K每一行向量的内积为了防止内积过大因此除以的平方根。Q乘以K的转置后得到的矩阵行列数都为 nn 为句子单词数这个矩阵可以表示单词之间的 attention 强度。下图为Q乘以1234 表示的是句子中的单词。Q乘以K的转置的计算得到之后使用 Softmax 计算每一个单词对于其他单词的 attention 系数公式中的 Softmax 是对矩阵的每一行进行 Softmax即每一行的和都变为 1.对矩阵的每一行进行 Softmax得到 Softmax 矩阵之后可以和V该词实际包含的信息内容相乘得到最终的输出Z。Self-Attention 输出上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数最终单词 1 的输出Z1等于所有单词 i 的值 Vi 根据 attention 系数的比例加在一起得到如下图所示Zi 的计算方法4.Multi-Head Attention在上一步我们已经知道怎么通过 Self-Attention 计算得到输出矩阵 Z而 Multi-Head Attention 是由多个 Self-Attention 组合形成的下图是论文中 Multi-Head Attention 的结构图。1输入层Q、K、V 向量最下面的三个输入分别是Q查询向量、K键向量、V值向量。它们通常来自同一个输入序列比如 “用毒毒毒蛇毒蛇会不会被毒毒死” 处理后的词向量经过不同的线性变换得到。每个Linear层的作用就是把原始输入映射到适合计算注意力的维度。2拆分多头并行计算注意力Self-Attention这一步图里没有画出来但逻辑上我们会把 Q、K、V 各自拆成h 组比如 h8。每组的维度是d_model/h比如 512/864这样就能同时跑 h 个独立的注意力计算。图里那层叠的灰色框就代表这 h 个并行的 “缩放点积注意力”Scaled Dot-Product Attention也就是自注意力计算Self-Attention。3核心计算缩放点积注意力自注意力计算Self-Attention每一组 Q、K、V 都会进入一个Scaled Dot-Product Attention模块。它会先计算 Q 和 K 的点积得到注意力分数再除以防止梯度爆炸最后通过 softmax 得到注意力权重。用这个权重去加权求和 V就得到了这一组的注意力输出。因为有 h 组所以会得到 h 个这样的输出向量。4拼接输出Concat把 h 个并行计算得到的注意力输出向量 ** 拼接Concat** 在一起就得到一个维度和原始输入一致的大向量比如 8×64512。5最终线性变换Linear拼接后的向量再经过最后一个Linear层做一次线性变换得到多头注意力的最终输出。这一步的作用是让模型可以学习如何更好地融合这 h 组注意力的信息。5.编码器Encoder1Add Norm 残差、归一化上图红色部分是 Transformer 的 Encoder block 结构可以看到是由 Multi-Head Attention,Add Norm, Feed Forward, Add Norm组成的。刚刚已经了解了 Multi-Head Attention 的计算过程现在了解一下 Add Norm 和 Feed Forward 部分。Add Norm 层由 Add 和 Norm 两部分组成其计算公式如下Add amp;amp;amp;amp;amp; Norm 公式其中X表示 Multi-Head Attention 或者 Feed Forward 的输入MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入X维度是一样的所以可以相加)。Add指XMultiHeadAttention(X)是一种残差连接通常用于解决多层网络训练的问题可以让网络只关注当前差异的部分在 ResNet 中经常用到残差连接Norm指 Layer Normalization通常用于 RNN 结构Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的这样可以加快收敛。2Feed ForwardFeed Forward 层比较简单是一个两层的全连接层第一层的激活函数为 Relu第二层不使用激活函数对应的公式如下Feed ForwardX是输入Feed Forward 最终得到的输出矩阵的维度与X一致。3组成了Encoder通过上面描述的Multi-Head Attention, Feed Forward, Add Norm 就可以构造出一个 Encoder blockEncoder block 接收输入矩阵 并输出一个矩阵 。通过多个 Encoder block 叠加就可以组成 Encoder。第一个 Encoder block 的输入为句子单词的表示向量矩阵后续 Encoder block 的输入是前一个 Encoder block 的输出最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C这一矩阵后续会用到 Decoder 中。