这里讲解 Transformer Block 中的前馈网络(Feed Forward Network,FFN)。它是编码器和解码器中的重要子层,通常位于多头注意力子层之后。

逐位置#
在 Transformer 中,前馈网络是逐位置(position-wise)的:它对输入中 每个位置 的词嵌入独立地应用 同一套 前馈网络参数,不涉及其他位置的信息。也就是说,FFN 对每个 token 的表示都是独立处理的,参数矩阵在所有位置共享。
为与自注意力一节保持一致,以下采用列优先表示:Xin∈Rd×n,其中每一列 xi∈Rd 是第 i 个 token 的表示;n 是序列长度,d 是特征维度。这个输入通常来自前一注意力子层;残差连接与 LayerNorm 的具体顺序见 Add & Norm。
一个标准的FFN包含两个线性层(Linear Layers),中间夹一个非线性激活函数(原始Transformer用ReLU,现代GPT/ViT多用GELU)。对于输入 Xin以及其单个token的 xi,前馈网络的计算公式为:
FFN(Xin)=W2σ(W1Xin+b11nT)+b21nTFFN(xi)=W2σ(W1xi+b1)+b2其中 σ 是逐元素激活函数,例如 ReLU 或 GELU;1n∈Rn 用于将偏置广播到所有 token 列。由单个位置的公式可见,FFN 对每个 xi 都是独立处理的;参数矩阵 W1,W2 与偏置向量 b1,b2 则在所有位置共享。
注意参数矩阵的维度
- W1∈Rdff×d,b1∈Rdff 用于将输入投影到更高维的隐藏空间,通常 dff 比 d 大很多(例如 dff=4d)。
- W2∈Rd×dff,b2∈Rd 用于将隐藏空间投影回原始维度。
第一层线性变换#
理解第一层线性变换,可以把矩阵 W1∈Rdff×d 看作一个 dff 个 行向量 的集合,而输入 Xin∈Rd×n 是一个 n 个列向量的集合。矩阵乘法 W1Xin 的结果是一个 dff×n 的矩阵,其中第 j 列是输入序列中第 j 个 token 的表示 xj 与 W1 每个行向量的点积结果。
←w1→←w2→⋮←wdff→↑xj↓=w1⋅xjw2⋅xj⋯wdff⋅xj第二层线性变换#
理解第二层线性变换,可以把矩阵 W2∈Rd×dff 看作一个 dff 个列向量的集合,将矩阵的每一列分别与输入向量 h(第一层激活输出)中的对应元素相乘,然后将所有经过缩放后的列相加起来。
↑w1↓↑w2↓⋯⋯⋯↑wdff↓h1h2⋮hdff=h1w1+h2w2+⋯+hdffwdffW2 的 列 与 嵌入空间 具有相同的维度,因此我们可以将列视为该空间中的各个方向。
结合激活函数的影响,输入第二层的列向量中的每个元素,被激活函数放大(正向)的元素会,会导致 W2 中对应的列对输出产生更大的贡献,而被抑制(负向或0)的元素则导致 W2 中对应的列对输出产生较小的贡献。
为什么需要FFN#
如果把 Transformer 比作一个“办公流程”:
常见的 dff=4d 是经验性的宽度设置;更宽的隐藏层能容纳更多特征组合与参数容量,但会增加计算和显存开销。现代模型也会采用其他扩张比例或门控 FFN(如 SwiGLU)。
FFN 本质上是一个庞大的 Key-Value 记忆网络。
计算过程:输入向量与所有 Key 做点积(计算相似度),经过激活函数过滤,再加权组合对应的 Value 输出。FFN 的两层计算产生一个“增量更新量”(Delta)。
CNN中的1x1卷积和FFN的相似#
在 CNN 中,1×1 卷积的作用是跨通道混合信息:只混合特征维度 c,不混合空间维度 (H,W)。
在 ViT 中,FFN 也是只混合特征维度 d,完全不混合序列维度 n。
多头注意力负责混合“空间/序列”信息(类似CNN的大卷积核),而FFN负责混合“通道/特征”信息(类似
CNN的1×1 卷积)。这种“空间-通道”交替处理的范式,是视觉模型(无论是CNN还是Transformer)的共同底层逻辑。