在 Transformer 模型中,QKV 输出的值通常会经过一个归一化步骤,随后通过一个多层感知机(MLP)来进一步处理。以下是这些步骤的详细说明:
计算输出
首先,我们根据注意力概率和值向量 V 计算每个词的输出。这里,我们使用之前计算的 Softmax 概率:
- 输出(你好) = Softmax(你好) · [V(你好), V(我), …, V(世界)]
- 输出(我) = Softmax(我) · [V(你好), V(我), …, V(世界)]
- 输出(美丽) = Softmax(美丽) · [V(你好), V(我), …, V(世界)]
- 输出(的) = Softmax(的) · [V(你好), V(我), …, V(世界)]
- 输出(编程) = Softmax(编程) · [V(你好), V(我), …, V(世界)]
- 输出(世界) = Softmax(世界) · [V(你好), V(我), …, V(世界)]
由于这些输出向量可能会因为加权求和而变得很大,我们通常会在通过 MLP 之前对它们进行归一化。
归一化
归一化通常采用以下两种方式之一:
- Layer Normalization:对每个输出向量独立进行归一化,计算其均值和标准差,然后进行缩放和平移。
- 均值(μ) = (输出(你好) + 输出(我) + … + 输出(世界)) / 6
- 标准差(σ) = sqrt(Σ[(输出(你好) - 均值)² + … + (输出(世界) - 均值)²] / 6)
- 归一化输出 = (输出 - 均值) / (σ + ε) * γ + β
其中,ε 是一个小的常数以避免除以零,γ 和 β 是可学习的参数。
- Batch Normalization:如果我们的数据是以批次形式处理的,我们可以使用批归一化。不过,这在 Transformer 模型中不常见。
多层感知机(MLP)
归一化之后,输出向量会通过一个 MLP,通常包括两个全连接层,第一个后面跟着一个激活函数(如 ReLU)。
- 第一层全连接:[输出向量] → Z = W₁ × [输出向量] + b₁
- 激活函数:A = ReLU(Z)
- 第二层全连接:[MLP输出] = W₂ × A + b₂
这里的 W₁、W₂、b₁ 和 b₂ 是可学习的参数。
完整的例子
让我们以“你好”的输出为例,展示这个过程:
- 假设“你好”的输出向量是 [o_你好]。
- 归一化 [o_你好] 得到 [n_你好]。
- 通过 MLP 处理 [n_你好] 得到最终的输出。
以下是伪代码:
# 假设输出向量
o_你好 = Softmax(你好) · [V(你好), V(我), ..., V(世界)]
# Layer Normalization
mean = np.mean(o_你好)
std = np.std(o_你好)
n_你好 = (o_你好 - mean) / (std + ε) * γ + β
# MLP
Z = W₁ @ n_你好 + b₁
A = ReLU(Z)
final_output_你好 = W₂ @ A + b₂
这里的 @
表示矩阵乘法,ReLU
是激活函数,ε
、γ
和 β
是 Layer Normalization 的参数,W₁
、W₂
、b₁
和 b₂
是 MLP 的权重和偏置。通过这个过程,我们得到了“你好”的最终输出,其他词的输出也以相同的方式计算。