跳转至

Transformer 精 简 笔记

我想完整还原最原始论文里的流程,会完整过一遍,并尽可能带上数学理解

架构图

1784031524160

Tip

下面的例子中:

  • \(d_{model}\) = 6

1. Encoder: Input Embedding 和位置编码

原论文使用的位置编码:

\[PE(pos, 2i) = \sin (\frac{pos}{10000^{2i/d_{model}}})\]
\[PE(pos, 2i + 1) = \cos (\frac{pos}{10000^{2i / d_{model}}})\]
等会儿再来解释

最初输入是:

\[X_E = \sqrt{d_{model}} E_{src} + PE\]

顺便把 decoder 的最初输入给说了

\[X_D = \sqrt{d_{model}} E_{target} + PE\]

2. Encoder: Multi-Head Self-Attention

不同头选择输入矩阵\(X\)的每个token的向量内部的线性组合(token之间不杂交),通过不同的\(W_{Q_i}\)\(W_{K_i}\)\(W_{V_i}\),得到\(Q_i\)\(K_i\)\(V_i\)

例如:

\[W_{Q_1}\in \mathbb{R}^{d_{model} \times d_k}, W_{K_1} \in \mathbb{R}^{d_{model} \times d_k}, W_{V_i} \in \mathbb{R}^{d_{model} \times d_v}\]
\[Q_1 = X W_{Q_1}\in \mathbb{R}^{n \times d_k}, K_1= XW_{K_1} \in \mathbb{R}^{n \times d_k}\]
\[V_1 = X W_{V_1} \in \mathbb{R}^{n \times d_v}\]

Note

\(Q, K\)的列数要一样(\(d_{k}\)),这样才能\(Q K^{\top}\)

\(Q, K, V\)的行数都是一样的,因为这样才能$softmax(\frac{Q K^{{\top}}}{\sqrt{d_{model}}}) V \(,当然这也是必然的,因为\)QKV\(是\)X$右乘权重矩阵得到的

然后把每个头的\(O_i = softmax(\frac{Q_i K_i^{{\top}}}{\sqrt{d_{model}}}) V_i\)直接拼起来

\[M_E = Concat(O_1, ..., O_t)\]

3. Encoder: Add & Norm

完整公式

\[H_E^{(1)} = LayerNorm(X_E^{(0)} + Dropout(M_E))\]
  • dropout = 0.1

先做残差相加:

\[R_E = X_E + M_E\]

Note

1784102567407

这个从 attention 前连到Add的箭头就是\(X_E\),是跳跃连接,残差

然后算LayerNorm,层归一化

算出每一行的均值和方差

\[LN(x) = \gamma \cdot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta \]

\(\gamma, \epsilon都是可训练参数(是行向量)\) \(\gamma\) 用于缩放 \(\beta\) 用于平移

行与行之间不干扰,最后得到\(H_E\)

4. Encoder: Feed Forward

\[FFN(x) = ReLU(xW_1+b_1) W_2 + b2\]

5. Encoder: 第二个 Add & Norm

\[Z_E = LayerNorm(H_E^{(1)} + F_E)\]

最后得到的就是Encoder对每个token的最终理解,每一行是一个token

最后的输出矩阵\(Z_E \in \mathbb{R}^{n \times d_{model}}\)

6. Decoder: Output Embedding + Position

1784103235850

和输入向量的处理一样

7. Decoder: Masked Multi-Head Self-Attention

依旧多头,Mask矩阵会加到分数矩阵上

\[S = \frac{Q K^{\top}}{\sqrt{d_k}}\]
\[M = \begin{bmatrix} 0 & -\infty & -\infty \\ 0 & 0 & -\infty \\ 0 & 0 & 0 \end{bmatrix}\]
\[S_{masked} = S + M\]

softmax之后\(-\infty\)就变成0了

然后把多头的自注意力输出concat起来得到\(M_D^{self}\)

8. Decoder: Add & Norm

\[H_D = LayerNorm(X_D + M_D^{self})\]

9. Encoder-Decoder Cross-Attention

1784115813209

  • \(Q\)来自Decoder
\[Q = X_D'W_Q^{cross}\]

\(X_D'\)是Masked Self-Attention后的 decoder 表示

  • \(K, V\)来自Encoder
\[K = Z_E W_K^{cross}\]
\[V = Z_E W_V^{cross}\]

分数矩阵:\(Q_D K_E^{T}\)

这里不需要mask,因为\(K_E\)是输入,\(Q_D\)是问题,都能看

然后每个头算出来一个\(A_{D, i}^{cross}\)

然后concat起来变成\(M_D^{cross}\)

10. Decoder: Add & Norm

\[H_D = LayerNorm(H_D + M_D^{cross})\]

11. Decoder: Feed Forward

\[F_D\]

12. Decoder: 再来一个 Add & Norm

\[Z_D = LayerNorm(H_D + F_D^{cross}) \in \mathbb{R}^{n_D\times d_{model}}\]

13. Linear: 从 6 维变成 8 个词表分数

1784118664373

最初的词表Embedding矩阵\(E \in \mathbb{R^{n \times d_{model}}}\)

\[L = Z_D E^{\top} = [n_D, d_{model}] \times [d_{model}, n_{E+D}]\]

得到 logits,\(n_D\)行,代表输出有几个位置,\(n_{E+D}\)列,代表所有出现的词,就是词表的词数

14. Softmax

1784119566777

每行做softmax,输出的每个位置就能选了

计算损失

每一行能算一个\(\mathcal{L}_t\)

\[\mathcal{L}_t = - \log p(y_t)\]
  • \(p(y_t)\)就是这一行里最大的那个概率

然后算出所有行的平均损失\(\bar{\mathcal{L}}\)

然后反向传播,会更新的参数:

  • Embedding
  • 所有权重矩阵\(W_{Q,K,V}\)
  • FFN的参数
  • LayerNorm的\(\gamma, \beta\)
  • ...

评论