什么是FFN层(Feed-Forward Network,前馈神经网络层)

FFN层(Feed-Forward Network,前馈神经网络层) 是Transformer等大模型里的核心模块,常放在注意力层之后,负责对每个位置的向量做独立的非线性特征加工,是模型"深度理解语义"的关键。

一、核心定位与结构

在Transformer中,FFN = 两层全连接(线性)+ 中间非线性激活 ,采用"升维→激活→降维"的标准流程:

  • 输入:维度为 d_model(如512、768、1024)
  • 第一步:线性层 → 升维到 d_ff(通常是 4 × d_model,如2048、3072、4096)
  • 第二步:激活函数(ReLU、GELU、SwiGLU等)→ 引入非线性
  • 第三步:线性层 → 降维回 d_model → 输出

数学形式(简化):
FFN(x)=W2⋅Act(W1⋅x+b1)+b2 \text{FFN}(x) = W_2 \cdot \text{Act}(W_1 \cdot x + b_1) + b_2 FFN(x)=W2⋅Act(W1⋅x+b1)+b2

  • W1∈Rdff×dmodelW_1 \in \mathbb{R}^{d_{\text{ff}} \times d_{\text{model}}}W1∈Rdff×dmodel,W2∈Rdmodel×dffW_2 \in \mathbb{R}^{d_{\text{model}} \times d_{\text{ff}}}W2∈Rdmodel×dff
  • Act\text{Act}Act 为激活函数

二、关键特点

  1. 逐位置独立处理(Position-wise)
    对序列中每个 token(词/字)的向量单独、并行计算,不依赖其他位置,和注意力的"全局交互"形成互补。
  2. 纯前馈、无循环
    信息只从输入到输出单向流动,没有递归/反馈,计算高效。
  3. 非线性能力
    两层线性+激活,让模型能拟合复杂的语义映射与特征组合,是Transformer突破线性表达瓶颈的关键。

三、在Transformer中的分工

  • 自注意力层 :负责全局关联,让每个 token 看到并融合所有位置的信息("谁和谁相关")。
  • FFN层 :负责局部精修,对每个 token 做深度非线性变换,提炼更抽象、更复杂的语义特征("如何理解这些信息")。

四、常见变体与演进

  • 激活函数:从早期 ReLU → 现在主流 GELU、SwiGLU(带门控,效果更好)。
  • 维度比例d_ff = 4 × d_model 是经典配置,部分模型用 2×、3× 或动态维度。
  • 稀疏化:如 MoE(混合专家),把 FFN 拆成多个专家,每个 token 只激活部分专家,提升效率与容量。

五、简单总结

FFN 是 Transformer 里的"逐位置非线性加工器",用"升维-激活-降维"的两层全连接结构,为模型提供强大的非线性表达能力,与注意力层一起构成现代大模型的核心计算单元。

六、完整代码实现

下面是包含 FFN 层、LayerNorm、残差连接的完整代码,可直接复制运行:

python 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F

class FeedForwardNetwork(nn.Module):
    """
    标准的 FFN 层实现(Transformer 中的 Position-wise Feed-Forward Network)
    结构:Linear1 → GELU → Dropout → Linear2 → Dropout
    """
    def __init__(self, d_model: int, d_ff: int = None, dropout: float = 0.1):
        super().__init__()
        # 默认 d_ff 为 d_model 的 4 倍(Transformer 经典配置)
        d_ff = d_ff or 4 * d_model
        # 第一层:升维(d_model → d_ff)
        self.w1 = nn.Linear(d_model, d_ff)
        # 第二层:降维(d_ff → d_model)
        self.w2 = nn.Linear(d_ff, d_model)
        # Dropout 层(防止过拟合)
        self.dropout = nn.Dropout(dropout)
        # 激活函数:GELU(当前大模型主流,比 ReLU 效果更好)
        self.act = nn.GELU()

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        前向传播
        Args:
            x: 输入张量,形状 [batch_size, seq_len, d_model]
        Returns:
            输出张量,形状与输入一致 [batch_size, seq_len, d_model]
        """
        # 升维 + 激活 + Dropout + 降维 + Dropout
        out = self.w1(x)       # [bs, seq_len, d_ff]
        out = self.act(out)    # 非线性激活
        out = self.dropout(out)
        out = self.w2(out)     # [bs, seq_len, d_model]
        out = self.dropout(out)
        return out

class TransformerEncoderBlock(nn.Module):
    """
    最小化的 Transformer 编码器块
    结构:LayerNorm → 自注意力 → 残差 → LayerNorm → FFN → 残差
    (注:这里简化了自注意力层,仅保留核心流程以展示 FFN 调用)
    """
    def __init__(self, d_model: int, n_head: int, dropout: float = 0.1):
        super().__init__()
        # 层归一化
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        # 自注意力层(简化版,仅用于演示流程)
        self.self_attn = nn.MultiheadAttention(
            embed_dim=d_model,
            num_heads=n_head,
            dropout=dropout,
            batch_first=True  # 输入形状为 [batch, seq, feature]
        )
        # FFN 层(调用上面实现的 FeedForwardNetwork)
        self.ffn = FeedForwardNetwork(d_model=d_model, dropout=dropout)
        self.dropout = nn.Dropout(dropout)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        前向传播
        Args:
            x: 输入张量,形状 [batch_size, seq_len, d_model]
        Returns:
            输出张量,形状与输入一致
        """
        # 第一步:自注意力 + 残差连接
        x_norm = self.norm1(x)
        attn_out, _ = self.self_attn(x_norm, x_norm, x_norm)  # 自注意力
        x = x + self.dropout(attn_out)  # 残差

        # 第二步:FFN + 残差连接(核心:调用 FFN 层)
        x_norm = self.norm2(x)
        ffn_out = self.ffn(x_norm)     # 调用 FFN 层
        x = x + self.dropout(ffn_out)  # 残差
        return x

# ------------------- 测试代码 -------------------
if __name__ == "__main__":
    # 超参数(符合常规 Transformer 配置)
    BATCH_SIZE = 2    # 批次大小
    SEQ_LEN = 10      # 序列长度
    D_MODEL = 512     # 模型维度
    N_HEAD = 8        # 注意力头数

    # 1. 创建 FFN 层实例并测试
    ffn = FeedForwardNetwork(d_model=D_MODEL)
    # 生成随机输入:[batch_size, seq_len, d_model]
    test_input = torch.randn(BATCH_SIZE, SEQ_LEN, D_MODEL)
    ffn_output = ffn(test_input)
    print("FFN 层输入形状:", test_input.shape)
    print("FFN 层输出形状:", ffn_output.shape)  # 应与输入一致 (2,10,512)

    # 2. 创建 Transformer 编码器块并测试 FFN 调用
    encoder_block = TransformerEncoderBlock(d_model=D_MODEL, n_head=N_HEAD)
    encoder_output = encoder_block(test_input)
    print("\nTransformer 块输出形状:", encoder_output.shape)  # (2,10,512)

七、代码关键部分解释

  1. FFN 层核心逻辑

    • __init__ 中定义了两层线性层:w1 负责升维(512→2048),w2 负责降维(2048→512),符合 Transformer 经典的 4 倍维度配置。
    • forward 方法严格遵循"升维→激活→Dropout→降维→Dropout"的流程,保证非线性表达能力的同时防止过拟合。
    • 激活函数使用 GELU(当前大模型如 BERT、GPT 均采用),比 ReLU 更适合自然语言处理场景。
  2. Transformer 块中 FFN 的调用

    • FFN 层在自注意力层之后执行,且和自注意力层一样,都遵循"预归一化 + 残差连接"的主流范式(先做 LayerNorm 再计算)。
    • 残差连接保证了梯度在深层网络中能有效传递,是 Transformer 能训练深层模型的关键,FFN 层的输出必须和输入维度一致才能做残差。
  3. 测试结果说明

    运行代码后会输出:

    复制代码
    FFN 层输入形状: torch.Size([2, 10, 512])
    FFN 层输出形状: torch.Size([2, 10, 512])
    
    Transformer 块输出形状: torch.Size([2, 10, 512])

    验证了 FFN 层输出维度和输入一致,符合 Transformer 残差连接的要求。

八、运行前置条件

  • 安装 PyTorch:pip install torch(建议 1.10 及以上版本)。
  • 无需其他依赖,代码仅使用 PyTorch 原生模块。

总结

  1. FFN 层的核心是"升维→非线性激活→降维",通过两层线性层+GELU实现,输出维度必须和输入一致以支持残差连接。
  2. 在 Transformer 块中,FFN 层紧跟自注意力层,且都需配合 LayerNorm 和残差连接使用。
  3. 代码中采用的"预归一化"(先做 LayerNorm 再计算)是当前 Transformer 实现的主流范式,比原始论文的"后归一化"更稳定。
相关推荐
咚咚王者1 小时前
人工智能之视觉领域 计算机视觉 第十章 图像直方图
人工智能·opencv·计算机视觉
claude_dev2 小时前
一步步搭建 Claude Code 的 MySQL MCP 服务器(附完整踩坑指南)
人工智能
liliangcsdn2 小时前
V-trace的核心公式与计算过程
人工智能·机器学习
小哈里2 小时前
【科研】ACM MM 论文 Latex 投稿模板修改(基于sample-sigconf-authordraft-v2.16)
人工智能·llm·科研·latex·cv·overleaf
优思学苑2 小时前
过程能力指标CPK高为何现场仍不稳?
大数据·人工智能·管理·pdca·管理方法
AaronZZH2 小时前
AG-UI:连接 AI 智能体与用户应用的开放协议
人工智能·ui
陈天伟教授2 小时前
人工智能应用- 人工智能交叉:05. 从 AlphaFold1 到 AlphaFold2
人工智能·神经网络·算法·机器学习·推荐算法
Eloudy2 小时前
CHI 开发备忘 03 记 -- CHI spec 03 网络层
人工智能·ai·arch·hpc
Together_CZ2 小时前
ViT-5: Vision Transformers for The Mid-2020s—— 面向2020年代中期的视觉Transformer
人工智能·深度学习·ai·transformer·vit·vit-5·面向2020年代中期的视觉