Skip to content

1.2 神经网络基础

大语言模型的底层构件是神经网络。无论是千亿参数的 GPT-4 还是开源的 LLaMA,其前向计算的本质仍然可以追溯到最经典的多层感知机(Multilayer Perceptron, MLP)结构——线性变换加非线性激活,再通过反向传播更新参数。与此同时,卷积神经网络(Convolutional Neural Network, CNN)在计算机视觉领域的演进历程,为深度学习积累了一系列至今仍在使用的核心设计范式:批量归一化、残差连接、深层架构等。

本节将从 MLP 的数学形式出发,深入剖析激活函数的设计演进(从 ReLU 到 GELU 再到 SwiGLU),给出前向传播与反向传播的完整推导,最后系统回顾 CNN 架构的演进史——从 AlexNet 到 ResNet,这段历史不仅是计算机视觉的发展主线,更是理解当代大模型设计哲学的重要背景。

1.2.1 多层感知机

线性模型的局限。 考虑一个简单的分类任务:给定输入特征向量 xRd,通过线性变换 o=Wx+b 输出预测值。线性模型蕴含着一个很强的假设——输出对输入的每个特征是单调的。这在某些场景下可以接受(例如收入越高,贷款违约概率越低),但对于图像分类这类任务则完全不适用——将图像某个像素值增大,不可能"总是"使模型更倾向于将其判定为猫或者狗。

更根本的问题在于:仿射变换的复合仍然是仿射变换。假设一个两层网络不使用任何非线性激活:

H=XW(1)+b(1),O=HW(2)+b(2)

将两式合并得到 O=XW(1)W(2)+b(1)W(2)+b(2),令 W=W(1)W(2), b=b(1)W(2)+b(2),则整个网络等价于单层线性模型 O=XW+b。换言之,没有非线性激活,无论堆叠多少层,网络的表达能力都不会增强。

引入非线性。 解决方案是在每个隐藏层的线性变换之后施加一个逐元素的非线性激活函数 σ()。对于一个单隐藏层的 MLP:

H=σ(XW(1)+b(1)),O=HW(2)+b(2)

其中 XRn×d 是包含 n 个样本的小批量输入,W(1)Rd×hW(2)Rh×q 分别是隐藏层和输出层的权重矩阵,h 是隐藏层的宽度。由于 σ 的存在,两层的复合不再能坍缩为单层,MLP 因此获得了建模非线性关系的能力。

万能近似定理。 Cybenko (1989) 和 Hornik (1991) 分别证明了一个重要理论结果:给定足够多的隐藏单元,即使是单隐藏层的 MLP 也可以以任意精度逼近任何连续函数。这个结论的深刻之处在于它保证了 MLP 的表达能力是充分的。但需要注意,"能表达"并不等于"能学到"——万能近似定理不保证梯度下降能够找到合适的参数,也不告诉我们需要多少隐藏单元。实践表明,使用更深(而非更宽)的网络通常能以更少的参数实现相同的逼近精度 (Simonyan 和 Zisserman, 2014)。

下面是一个完整的 PyTorch MLP 示例,用于 MNIST 手写数字分类:

python
import torch
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self, input_dim=784, hidden_dim=256, num_classes=10):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, num_classes),
        )

    def forward(self, x):
        return self.net(x.view(x.size(0), -1))

model = MLP()
print(f"参数总量: {sum(p.numel() for p in model.parameters()):,}")
# 参数总量: 269,322

1.2.2 激活函数:从 ReLU 到 SwiGLU

激活函数的选择直接影响网络的训练效率和最终性能。深度学习发展至今,激活函数经历了从 Sigmoid/Tanh 到 ReLU、再到 GELU 和 SwiGLU 的演进,每一步都对应着对训练难题的更深刻理解。

Sigmoid 与 Tanh 的衰落。 早期神经网络普遍使用 Sigmoid 函数 σ(x)=1/(1+ex) 和 Tanh 函数 tanh(x)=(1e2x)/(1+e2x)。它们的共同问题是梯度消失(Vanishing Gradient):当输入 |x| 较大时,导数趋近于零。Sigmoid 的最大导数仅为 0.25(在 x=0 处取到),这意味着每经过一层,梯度至少衰减为原来的四分之一。在深层网络中,梯度经过层层衰减后几乎为零,导致浅层参数无法有效更新。此外,Sigmoid 的输出不是零中心的(输出全为正值),这会导致梯度更新时参数只能同步增大或同步减小,降低优化效率。

ReLU:简洁高效的里程碑。 ReLU(Rectified Linear Unit)由 Nair 和 Hinton (2010) 引入深度学习:

ReLU(x)=max(0,x)

ReLU 的优势很明显:当 x>0 时梯度恒为 1,不会发生梯度消失;计算仅涉及阈值比较,极其高效。ReLU 的广泛使用是深度学习在 2010 年代复兴的关键推动力之一。AlexNet 的成功在很大程度上归功于用 ReLU 替换了传统的 Sigmoid。

然而 ReLU 存在一个已知缺陷——Dying ReLU 问题:如果某个神经元的输入在训练过程中恒为负值,其输出和梯度都为零,对应的权重将永远无法更新,该神经元"死亡"。Leaky ReLU(f(x)=max(αx,x), α0.01)和 PReLU(α 可学习)通过允许负值区域有微小梯度来缓解这一问题。

GELU:平滑的概率门控。 GELU(Gaussian Error Linear Unit)由 Hendrycks 和 Gimpel (2016) 提出:

GELU(x)=xΦ(x)

其中 Φ(x)=12[1+erf(x2)] 是标准正态分布的累积分布函数。直观理解:GELU 以输入值本身的大小作为"概率权重"来决定是否让信号通过——较大的正值几乎完全通过(Φ(x)1),较大的负值几乎完全被抑制(Φ(x)0),而接近零的值则以接近 0.5 的概率被保留。与 ReLU 在 x=0 处的硬切换不同,GELU 在全域上光滑可微,有助于优化器更稳定地更新参数。

GELU 被 GPT、GPT-2、GPT-3 以及 BERT 等模型广泛采用,在 Transformer 架构的 FFN(Feed-Forward Network)模块中取代了 ReLU。

SwiGLU:门控机制的胜利。 [选读] SwiGLU 是当前大语言模型中最主流的激活方案,由 Shazeer (2020) 在系统实验中确立。它是两个思想的组合:Swish 激活函数门控线性单元(Gated Linear Unit, GLU)。

Swish 函数定义为 Swish(x)=xσ(x),其中 σ 是 Sigmoid 函数。当 β=1 时,Swish 等价于 SiLU(Sigmoid Linear Unit),其形状介于 ReLU 和 GELU 之间,在负值区域允许小幅度的负输出。

GLU 的核心思想是引入一个可学习的门控向量来动态调节信息流。标准 FFN 的计算为 FFN(x)=σ(xW1)W2,而 GLU 变体将其改为:

FFNGLU(x)=(σ(xWgate)xWup)Wdown

其中 表示逐元素乘法,Wgate 产生门控信号,Wup 负责升维变换。SwiGLU 使用 Swish 作为门控激活函数:

SwiGLU(x)=(Swish(xWgate)xWup)Wdown

注意 SwiGLU 引入了三个权重矩阵(Wgate,Wup,Wdown),比标准 FFN 的两个矩阵多了一个。为了保持总参数量不变,通常将中间维度从 4h 调整为 8h3(在实际工程中再对齐到 256 的整数倍以优化 GPU 计算效率)。

python
import torch
import torch.nn as nn
import torch.nn.functional as F

class SwiGLU_FFN(nn.Module):
    """LLaMA 风格的 SwiGLU 前馈网络"""
    def __init__(self, hidden_dim, multiple_of=256):
        super().__init__()
        mid_dim = int(8 * hidden_dim / 3)
        mid_dim = multiple_of * ((mid_dim + multiple_of - 1) // multiple_of)
        self.gate = nn.Linear(hidden_dim, mid_dim, bias=False)
        self.up   = nn.Linear(hidden_dim, mid_dim, bias=False)
        self.down = nn.Linear(mid_dim, hidden_dim, bias=False)

    def forward(self, x):
        return self.down(F.silu(self.gate(x)) * self.up(x))

ffn = SwiGLU_FFN(hidden_dim=512)
x = torch.randn(2, 10, 512)  # (batch, seq_len, hidden_dim)
print(ffn(x).shape)  # torch.Size([2, 10, 512])

以下表格总结了各激活函数的关键特性和典型应用:

激活函数公式特点典型应用
ReLUmax(0,x)简单高效,正区梯度恒为 1原始 Transformer, T5
GELUxΦ(x)平滑可微,概率门控GPT 系列, BERT
SwiGLUSwish(xWg)xWu门控机制,三矩阵结构LLaMA, PaLM, Mistral

激活函数的演进揭示了一个清晰的趋势:从简单的硬阈值(ReLU),到平滑的概率门控(GELU),再到可学习的动态门控(SwiGLU),模型获得了越来越强的表达能力。2023 年之后发布的几乎所有主流 LLM 都采用了 SwiGLU。

1.2.3 前向传播与反向传播

理解前向传播与反向传播的数学机制是深度学习的必修课。虽然现代框架(PyTorch、JAX 等)已经实现了自动微分,但掌握反向传播的原理有助于理解梯度消失/爆炸、学习率选择、参数初始化等核心问题。

前向传播。 考虑一个含单隐藏层的 MLP(为简化,省略偏置项)。给定输入 xRd,前向计算依次进行:

z=W(1)x,h=ϕ(z),o=W(2)h

其中 W(1)Rh×d, W(2)Rq×hϕ 是激活函数。损失函数为 L=(o,y),若加上 2 正则化项 s=λ2(W(1)F2+W(2)F2),则最终的目标函数为 J=L+s

前向传播的过程就是按照从输入到输出的顺序,逐层计算并存储每个中间变量(z, h, o)。这些中间变量将在反向传播中被复用。

反向传播。 [必读] 反向传播基于微积分的链式法则,从输出层向输入层逆序计算目标函数对每个参数的梯度。以上述网络为例,完整的反向传播推导如下:

第一步,计算目标函数对输出层变量的梯度:

Jo=Lo

若使用交叉熵损失配合 Softmax 输出,可以证明这等于 ay(模型预测概率减去真实标签的 one-hot 编码),形式极为简洁。

第二步,计算对输出层权重 W(2) 的梯度:

JW(2)=Joh+λW(2)

第三步,将梯度信号传递到隐藏层:

Jh=W(2)Jo

第四步,经过激活函数反传(逐元素乘法):

Jz=Jhϕ(z)

其中 表示 Hadamard 积(逐元素乘法),ϕ(z) 是激活函数的导数在 z 处的值。

第五步,计算对隐藏层权重 W(1) 的梯度:

JW(1)=Jzx+λW(1)

一般公式。 对于具有 n 层的网络,定义 δi 为损失对第 i 层 logits zi 的梯度,则可以写出统一的递推公式:

δn=any(输出层,Softmax + 交叉熵的特殊简化)δi=δi+1(W(i+1))ϕ(zi)(隐藏层递推)LW(i)=(a(i1))δi,Lb(i)=k=1Nδki

其中 a(i1) 是第 i1 层的激活输出(a(0)=x),N 是批量大小。注意权重梯度是矩阵乘法,偏置梯度是 δ 矩阵按样本维度求和——这一不对称性源于偏置参数在同一批次的所有样本间共享。

关于内存的注意事项。 前向传播需要存储所有中间激活值以供反向传播使用。这意味着训练时的显存占用远大于推理:中间激活的存储量与网络层数和批量大小成正比。这也是训练深层网络容易出现 OOM(Out of Memory)的根本原因,理解这一点对后续的混合精度训练、梯度检查点等优化技术至关重要。

1.2.4 卷积神经网络演进史

虽然大语言模型的主干架构是 Transformer,但 CNN 在 2012-2015 年间的演进历程为深度学习积累了许多关键设计范式——包括深层网络的可行性论证、残差连接的发明、批量归一化等。这些思想被直接继承到了 Transformer 架构中。

AlexNet:深度学习的起点(2012)。 2012 年,Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 提出的 AlexNet 在 ImageNet 大规模视觉识别挑战赛(ILSVRC)中以压倒性优势获胜,将 Top-5 错误率从上一年的 26% 降低到 15%,领先第二名超过 10 个百分点。这一结果震动了整个计算机视觉界,标志着深度学习时代的正式开启。

AlexNet 三位作者合影(从左至右:Alex Krizhevsky, Ilya Sutskever, Geoffrey Hinton)

图 1-4:AlexNet 三位作者合影。Hinton 后来被誉为"深度学习之父"并获诺贝尔物理学奖,Sutskever 成为 OpenAI 联合创始人。

AlexNet 的架构包含 5 个卷积层和 3 个全连接层,总参数量约 6000 万。它有若干关键创新:

  • ReLU 激活函数:首次在大型网络中使用 ReLU 替代 Sigmoid/Tanh,训练速度提升数倍且有效缓解了梯度消失问题。
  • Dropout 正则化:在全连接层以 50% 的概率随机丢弃神经元,大幅减少过拟合。
  • GPU 并行训练:首次利用两块 GPU 分模型并行训练,开创了 GPU 加速深度学习的先河。
  • 数据增强:通过随机裁剪、水平翻转和颜色扰动扩充训练数据。

AlexNet 的意义远超一次竞赛的胜利——它向世界证明了"更深的网络 + 大规模数据 + 强大算力"这一组合的威力,直接催生了后续 CNN 的快速迭代。

VGG:深度与简洁的力量(2014)。 来自牛津大学视觉几何组(Visual Geometry Group)的 Simonyan 和 Zisserman 提出了 VGG 网络。VGG 的核心思想极其简洁:用重复堆叠的 3×3 小卷积核替代大卷积核

VGG 网络架构示意图

图 1-5:从 AlexNet 到 VGG 的架构演进。VGG 将网络组织为重复的"卷积块",每个块包含若干个 3×3 卷积层和一个 2×2 最大池化层,结构极为规整。

这一设计蕴含着精妙的参数效率考量:两个 3×3 卷积的感受野等价于一个 5×5 卷积,但参数量仅为 2×9c2=18c2,而 5×5 卷积需要 25c2 个参数。更重要的是,两层卷积之间插入了非线性激活,增强了网络的表达能力。VGG 通过这种设计将网络深度推进到 16-19 层(VGG-16/VGG-19),并通过系统实验证明了深而窄的网络显著优于浅而宽的网络

VGG 的另一个贡献是确立了"网络家族"的概念:通过一个统一的配置模板(arch 参数)定义一系列不同复杂度的网络变体,供使用者在速度和精度之间灵活权衡。这种模块化设计思想至今仍是深度学习架构设计的标准做法。

Inception/GoogLeNet:多尺度并行(2014)。 同年,Google 的 Szegedy 等人提出了 Inception 模块。其核心思想是在同一层中并行使用不同尺度的卷积核1×1, 3×3, 5×5)以及最大池化,然后将所有分支的输出在通道维度上拼接。1×1 卷积在此扮演了降低通道数以控制计算量的关键角色。GoogLeNet(Inception v1)仅用约 500 万参数就在 ILSVRC 2014 中获得冠军,远少于 VGG 的 1.38 亿参数,展示了精巧的架构设计对计算效率的巨大影响。

ResNet:残差连接的革命(2015)。 到了 2015 年,深度网络的训练遇到了一个令人困惑的现象:随着网络层数的增加,训练误差反而上升。注意,这不是过拟合(过拟合表现为训练误差低但测试误差高),而是更深的网络在训练集上的表现就不如更浅的网络。这被称为退化问题(Degradation Problem)。

ResNet 论文中的退化现象:56 层网络的训练误差和测试误差均高于 20 层网络

图 1-6:退化问题的实验证据。左图为训练误差,右图为测试误差。56 层网络在两个指标上均劣于 20 层网络,这说明问题不在于过拟合,而在于优化困难。

何恺明等人对此给出了一个优雅的解决方案——残差连接(Residual Connection)。其核心观察是:如果我们希望某些层学习恒等映射 H(x)=x(即这些层"不做事"),那么让网络直接学习 H(x) 是困难的,但让网络学习残差 F(x)=H(x)x 则容易得多——只需要将 F(x) 的参数推向零即可。于是输出变为:

y=F(x)+x

残差块的结构示意图

图 1-7:残差块(Residual Block)。输入 x 通过两条路径:主路径经过卷积-激活-卷积变换得到 F(x),捷径(shortcut)直接将 x 传到输出端,两者相加后再经过 ReLU 激活。

残差连接带来了两个根本性的好处:

  1. 梯度直通:反向传播时,梯度可以通过捷径直接传递到浅层,避免了深层网络中梯度经过层层连乘而衰减的问题。
  2. 表达能力单调递增:如果新增的层不能提升性能,它只需要学习将 F(x) 置零,网络就退化为更浅的版本。因此更深的 ResNet 至少不会比更浅的版本差。

ResNet 在 2015 年 ILSVRC 中以 3.57% 的 Top-5 错误率夺冠,首次超越了人类水平(约 5.1%)。其网络深度突破性地达到 152 层(后续研究甚至尝试了 1000 层以上的变体)。ResNet 论文成为 21 世纪引用量最高的学术论文之一。

更深远的影响在于,残差连接已经超越了 CNN 的范畴,成为几乎所有深度神经网络的标准组件。在 Transformer 架构中,每个注意力子层和 FFN 子层都采用了残差连接(x+Sublayer(x)),这正是 ResNet 思想的直接传承。

下面给出一个 PyTorch 残差块的实现:

python
import torch
import torch.nn as nn

class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super().__init__()
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.bn1   = nn.BatchNorm2d(channels)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.bn2   = nn.BatchNorm2d(channels)
        self.relu  = nn.ReLU(inplace=True)

    def forward(self, x):
        residual = x
        out = self.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out += residual  # 残差连接
        return self.relu(out)

block = ResidualBlock(channels=64)
x = torch.randn(1, 64, 32, 32)
print(block(x).shape)  # torch.Size([1, 64, 32, 32])

以下表格梳理了 CNN 架构演进的关键里程碑:

年份模型深度参数量ILSVRC Top-5核心贡献
2012AlexNet8 层~60M15.3%ReLU, Dropout, GPU 训练
2014VGG-1616 层~138M7.3%3×3 卷积堆叠, 网络家族
2014GoogLeNet22 层~5M6.7%Inception 多尺度并行, 1×1 卷积
2015ResNet-152152 层~60M3.57%残差连接, 超越人类水平

1.2.5 本节小结

本节从 MLP 的基础数学形式出发,系统梳理了神经网络的三大支柱:网络结构、激活函数和训练算法。激活函数从 ReLU 的硬阈值截断,到 GELU 的平滑概率门控,再到 SwiGLU 的可学习门控机制,每一步演进都在追求更强的表达能力和更稳定的训练动态,SwiGLU 已成为当代 LLM 的标准配置。反向传播通过链式法则将损失信号逆向传递至每个参数,是所有梯度优化方法的数学基础。CNN 的演进史则展示了深度学习领域的核心设计哲学——通过更深的网络、更精巧的模块化设计和残差连接来扩展模型能力。尤其是残差连接,它从 ResNet 出发,已成为包括 Transformer 在内的几乎所有深度架构的标配组件,是连接经典 CNN 时代与大模型时代的关键桥梁。