逐位置前馈网络(FFN)是每个编码器和解码器层中的重要组成部分。这些网络处理向量 (vector),为模型增加进一步的处理能力。
尽管名称如此,它实际上是一个非常简单的网络。它由两次线性变换组成,中间夹有一个整流线性单元(ReLU)激活函数 (activation function)。“逐位置”的部分很要紧:这个相同的前馈网络在序列中的每个位置(即每个词元 (token)的表示)上独立且相同地应用。
因此,如果在注意力子层之后您的输入序列表示具有 (序列长度, dmodel) 的维度,FFN 会使用同一组权重 (weight)分别处理每个大小为 dmodel 的 序列长度 向量。在此阶段,它不考虑不同位置之间的关系;这种交互发生在注意力层中。
FFN 的结构
应用于每个位置 x 的变换可以表示为:
FFN(x)=ReLU(xW1+b1)W2+b2
其中:
- x 是前一层(注意力机制 (attention mechanism)后的残差连接与层归一化 (normalization)层)对于特定位置的输出。
- W1 和 b1 是第一次线性变换的权重 (weight)矩阵和偏置 (bias)项。
- W2 和 b2 是第二次线性变换的权重矩阵和偏置项。
- ReLU 是整流线性单元激活函数 (activation function),定义为 ReLU(z)=max(0,z)。
FFN 内部的维度通常会发生变化。输入和输出维度是 dmodel(模型的嵌入 (embedding)维度),但内部层维度(通常表示为 dff)通常更大。一种常见配置(如最初的 Transformer 论文中所用)是 dff=4×dmodel。例如,如果 dmodel=512,则 dff=2048。
- 第一个线性层将 dmodel 维输入向量 (vector) x 投影到更高维空间 (high-dimensional space) (dff)。
- ReLU 激活引入非线性,使模型能够学习更复杂的函数。如果没有像 ReLU 这样的非线性,堆叠多层并不会比单个线性变换增加太多模型能力。
- 第二个线性层将结果投影回原始 dmodel 维度,为下一层或模块做好准备。
应用于单个位置向量表示的逐位置前馈网络示意图。
为什么要使用它?
您可能想知道为什么在注意力机制 (attention mechanism)之后还需要这个组成部分。注意力机制处理序列级别的交互和上下文 (context)聚合,而 FFN 则在每个位置独立地提供额外的计算深度和非线性。
- 增加模型容量: 它增加了可学习参数 (parameter),增加了模型表示每个词元 (token)特征内部复杂模式的能力。
- 非线性: 如前所述,ReLU 激活对于模型学习非线性关系是不可或缺的。注意力层本身内部通常涉及线性变换,因此 FFN 增加了必要的非线性处理。
- 特征变换: 它可以被视为将通过注意力机制学习到的特征变换为更合适的表示,以便用于下一层或模块。扩展到 dff 并收缩回 dmodel 允许网络在将特征投影回来之前,可能在更高维空间 (high-dimensional space)中学习更丰富的特征组合。
尽管简单,逐位置前馈网络是每个 Transformer 模块不可或缺的部分,与注意力机制以及残差连接与层归一化 (normalization)层配合工作,以有效处理序列信息。它显著提升了 Transformer 架构的整体性能。