PAGE 02 · AI 基础理论

🕸️ 神经网络与深度学习

从 1943 年的 McCulloch-Pitts 神经元模型,到 2012 年 AlexNet 引爆深度学习革命,再到 Transformer 改变一切——完整梳理神经网络的思想演进

🧠 一、从感知机到神经网络

1.1 生物神经元:一切灵感的起点

1943 年,神经生理学家 Warren McCulloch 和数学家 Walter Pitts 提出了第一个人工神经元模型 McCulloch-Pitts 神经元,首次用数学方式描述了生物神经元的工作原理 [1]

🔬 生物神经元的关键特征

树突 (Dendrites):接收来自其他神经元的信号输入

细胞体 (Soma):对输入信号进行加权求和

轴突 (Axon):将处理后的信号传递给下游神经元

突触 (Synapse):连接点,决定信号传递的强度(权重)

y = f( Σᵢ wᵢxᵢ + b ) ← 人工神经元的数学抽象

1.2 感知机:第一个可学习的模型 (1958)

1958 年,Frank Rosenblatt 在康奈尔航空实验室发明了感知机 (Perceptron)——第一个可以通过数据自动学习权重的模型 [1]。它使用了一个简单的学习规则来调整权重:

wᵢ ← wᵢ + η · (y_true − y_pred) · xᵢ
⚠️ 感知机的致命局限 1969 年,Marvin Minsky 和 Seymour Papert 在《Perceptrons》一书中证明:单层感知机无法解决 XOR(异或)问题。因为 XOR 不是线性可分的——你无法用一条直线将 XOR 的两种输出分开。这一结论直接导致了 AI 的第一次"寒冬"(1974-1980)。

1.3 多层感知机 (MLP):突破 XOR

解决方案很简单:增加隐藏层。一个只有 2 个隐藏神经元的多层感知机就能完美解决 XOR 问题。

多层感知机 (MLP) 结构图
输入层
x₁
x₂
隐藏层
h₁
h₂
h₃
h₄
输出层
y

蓝色圆圈 = 输入神经元  |  紫色圆圈 = 隐藏层神经元  |  绿色圆圈 = 输出神经元
每条连接线上都有一个可学习的权重 wᵢⱼ

✅ XOR 问题的直觉解释 隐藏层将输入空间变换到一个新的表示空间,在这个新空间里,原来不可分的数据变得线性可分。这本质上就是特征学习 (Feature Learning)的雏形——也是深度学习的核心思想。

1.4 反向传播算法:让深度学习成为可能 (1986)

多层网络的关键问题是:如何高效地计算每个权重的梯度? 1986 年,Rumelhart、Hinton 和 Williams 发表了里程碑论文,将反向传播 (Backpropagation)算法普及开来 [2]

📐 反向传播的核心思想(链式法则)

前向传播:输入数据逐层计算,得到预测输出。

计算损失:用损失函数衡量预测与真实值的差距。

反向传播:利用链式法则 (Chain Rule),从输出层向输入层逐层计算损失对每个权重的偏导数。

∂L/∂wᵢⱼ = ∂L/∂aⱼ · ∂aⱼ/∂zⱼ · ∂zⱼ/∂wᵢⱼ

权重更新:梯度下降沿梯度反方向调整权重,减小损失。

wᵢⱼ ← wᵢⱼ − η · ∂L/∂wᵢⱼ
💡 历史轶事 反向传播的链式法则思想早在 1970 年代就被多位研究者独立发现(包括 Paul Werbos 的 1974 年博士论文),但直到 1986 年 Rumelhart 等人在 Nature 发表后,才被广泛认知和应用。这也是 Geoffrey Hinton 后来被称为"深度学习之父"的原因之一。

⚙️ 二、深度学习的关键组件

2.1 激活函数:神经网络的"非线性灵魂"

如果没有激活函数,无论网络多深,都等价于一个线性变换。激活函数为网络引入非线性,使其能够拟合任意复杂的函数。

激活函数 公式 优点 缺点 典型应用
Sigmoid σ(x) = 1/(1+e⁻ˣ) 输出在 (0,1),适合概率 梯度消失;输出非零中心 二分类输出层
Tanh tanh(x) 零中心输出,收敛更快 仍有梯度消失问题 RNN 隐藏层
ReLU max(0, x) 计算极快;缓解梯度消失 负区"死亡";非零中心 隐藏层默认选择
Leaky ReLU max(αx, x), α=0.01 解决"死亡 ReLU"问题 效果提升有限 ReLU 的替代
GELU x·Φ(x) 平滑的非线性;BERT/GPT 使用 计算稍复杂 Transformer 模型
Swish x·σ(βx) 平滑、无上界;优于 ReLU 额外 sigmoid 计算 EfficientNet 等
📈 演进趋势 深度学习早期以 Sigmoid/Tanh 为主 → 2012 年 AlexNet 大规模采用 ReLU → 2020s GELU 和 Swish 在 Transformer 架构中成为主流。核心趋势是从"平滑但有梯度消失问题"走向"计算高效且非饱和"。

2.2 损失函数:衡量预测的好坏

损失函数 公式 适用场景
均方误差 (MSE) L = 1/n Σ(yᵢ − ŷᵢ)² 回归任务(房价预测等)
交叉熵 (CE) L = −Σ yᵢ log(ŷᵢ) 分类任务(图像分类等)
二元交叉熵 (BCE) L = −[y log(ŷ) + (1−y)log(1−ŷ)] 二分类任务
Focal Loss CE × (1−pᵗ)ᵞ 类别不平衡问题

2.3 优化器:如何高效地找到最优解

优化器决定了模型参数如何根据梯度进行更新。从最基本的 SGD 到如今广泛使用的 AdamW,优化器的发展经历了多次重要演进。

1951 SGD(随机梯度下降)

最朴素的优化方法:w ← w − η·∇L。简单但对学习率敏感,容易陷入局部最优和鞍点。

2011 AdaGrad

自适应学习率——对出现频率低的参数给更大的学习率。但学习率单调递减,后期容易"过度衰减"。

2014 RMSProp

Hinton 提出,通过指数加权移动平均解决 AdaGrad 学习率衰减过快的问题。

2015 Adam ⭐

Kingma & Ba 提出,结合了 Momentum(一阶矩)和 RMSProp(二阶矩)的优势。自适应学习率 + 动量,成为深度学习默认优化器

mₜ = β₁mₜ₋₁ + (1−β₁)gₜ   |   vₜ = β₂vₜ₋₁ + (1−β₂)gₜ²   |   w ← w − η·m̂ₜ/(√v̂ₜ + ε)
2017 AdamW ⭐

Loshchilov & Hutter 提出,将权重衰减 (Weight Decay) 从梯度更新中解耦,效果优于 Adam + L2 正则化。Transformer 训练的标配。

2.4 正则化:防止过拟合的艺术

.Dropout (2014)

Srivastava 等人提出。训练时以概率 p 随机"丢弃"神经元,迫使网络学习更鲁棒的特征。相当于训练了一个隐式的模型集成

训练时:hᵢ = hᵢ · Bernoulli(p) / p

Batch Normalization (2015)

Ioffe & Szegedy 提出。对每个 mini-batch 的输出进行标准化,使其均值为 0、方差为 1。加速训练、允许更大学习率、有轻微正则化效果。

ŷ = γ · (x − μ_batch)/σ_batch + β

Layer Normalization (2016)

单个样本的所有特征进行标准化(而非 batch 维度)。在 RNN 和 Transformer 中效果优于 BatchNorm,因为不依赖 batch size。

ŷ = γ · (x − μ_layer)/σ_layer + β

权重衰减 (L2 Regularization)

在损失函数中加入权重大小的惩罚项,防止权重过大导致过拟合。本质上是 Occam's Razor 的数学实现——偏好更简单的模型。

L_total = L_task + λ · Σ||w||²

2.5 梯度消失与梯度爆炸

这是深度网络训练中最经典的问题之一,尤其在 RNN 中尤为严重。

📉 梯度消失 (Vanishing Gradients)

当网络层数很多时,根据链式法则,梯度会在反向传播过程中逐层相乘。如果每层的梯度都小于 1,多层相乘后梯度趋近于 0,导致前面的层几乎不更新。

∂L/∂w₁ = ∂L/∂yₙ · ∂yₙ/∂yₙ₋₁ ··· ∂y₂/∂y₁ · ∂y₁/∂w₁

📈 梯度爆炸 (Exploding Gradients)

反之,如果每层梯度大于 1,多层相乘后梯度会指数级增长,导致权重更新剧烈震荡,训练不稳定甚至 NaN。

🔧 解决方案

ReLU 激活函数正区间梯度恒为 1,天然缓解梯度消失
残差连接 (ResNet)梯度可以直接通过捷径传播,不经过中间层
梯度裁剪限制梯度的最大范数,防止爆炸:g = g · max_norm / ||g||
Batch/Layer Norm稳定各层输出的分布,使梯度更稳定
合理初始化Xavier / He 初始化,确保初始时各层输出方差一致
LSTM / GRU门控机制控制信息流,解决 RNN 的梯度消失

🖼️ 三、CNN 卷积神经网络

3.1 发展历程

1989 LeNet 前身

Yann LeCun 使用卷积网络识别手写邮政编码,验证了卷积操作的有效性。

1998 LeNet-5 ⭐

LeCun 发表的 LeNet-5 是第一个成功的 CNN 架构,用于识别 MNIST 手写数字(准确率 99.2%)。包含卷积层、池化层和全连接层的经典结构 [3]

2012 AlexNet 🚀 深度学习元年

Alex Krizhevsky、Ilya Sutskever、Geoffrey Hinton 用 AlexNet 在 ImageNet 竞赛中取得历史性突破:Top-5 错误率从 26.2%(传统方法)降至 15.3%,领先第二名 10 个百分点 [4]。关键技术:ReLU、Dropout、GPU 训练、数据增强。

2014 VGGNet

Simonyan & Zisserman 证明"更深的网络 + 更小的卷积核(3×3)= 更好的性能"。VGG-16/VGG-19 成为特征提取的标准架构。

2015 ResNet 🏆 百层网络

何恺明等提出残差连接 (Skip Connection),成功训练了 152 层的超深网络,获得 ImageNet 冠军(Top-5 错误率 3.57%)。残差公式:H(x) = F(x) + x——让网络学习"残差"而非直接映射。

3.2 核心操作详解

🔲 卷积 (Convolution)

用一个小型"卷积核"(如 3×3)在输入图像上滑动,提取局部特征。卷积核的权重通过学习自动获得。

  • 参数共享:同一个卷积核应用于所有位置
  • 局部连接:每个神经元只看局部区域
  • 平移不变性:物体在哪里都能检测到
Output(i,j) = Σₘ Σₙ Input(i+m, j+n) · Kernel(m,n)

📐 池化 (Pooling)

对局部区域进行降采样,减少参数量,提供平移不变性。

  • 最大池化:取区域内最大值
  • 平均池化:取区域平均值
  • 典型设置:2×2 池化,步长 2

🔗 全连接 (FC)

将卷积/池化层提取的特征展平,输入传统的全连接层进行分类。

  • CNN 的早期模型末尾使用 FC 层
  • 现代架构逐渐用全局平均池化替代
  • FC 层参数量最大,易过拟合

3.3 案例详解:AlexNet 如何改变历史

🏆 ImageNet 2012 的突破

竞赛背景:ImageNet 包含 1400 多万张图片、2 万多个类别。2010-2011 年的冠军都是传统计算机视觉方法(SIFT + HOG + SVM),Top-5 错误率约 25-28%。

AlexNet 的创新

  • 深度:8 层网络(5 个卷积 + 3 个全连接),比之前深得多
  • ReLU:替代 Sigmoid,训练速度提升 6 倍
  • GPU 并行:使用两块 GTX 580 GPU 分布式训练
  • Dropout:在全连接层使用 p=0.5 的 Dropout
  • 数据增强:随机裁剪、水平翻转、颜色抖动

结果:Top-5 错误率 15.3%,比第二名(26.2%)低了 10.9 个百分点。这在顶级竞赛中史无前例,直接引爆了全球深度学习热潮。

3.4 应用场景

🔍 图像分类

判断图片中的主体类别。从 AlexNet 到 ResNet,ImageNet Top-5 错误率已降至 2-3%,超越人类水平(约 5%)。

🎯 目标检测

不仅识别类别,还定位目标的位置(边界框)。经典方法:R-CNN → Fast R-CNN → YOLO → DETR。

👤 人脸识别

从 FaceNet 的 Embedding 距离到 ArcFace 的角度间隔损失函数,CNN 让人脸识别从实验室走入日常生活。

🏥 医学影像

在 X 光、CT、MRI 等医学影像分析中,CNN 的准确率已接近甚至超过专业医生,用于癌症筛查、病变检测等。

🔁 四、RNN 循环神经网络

4.1 处理序列数据的动机

自然界充满了序列数据:文本是一串单词、语音是一串声学信号、视频是一串帧、股票是一串价格……前馈神经网络(MLP、CNN)假设输入之间相互独立,无法捕捉序列中的时序依赖关系

RNN 的核心创新:引入隐藏状态 (Hidden State) hₜ 作为"记忆",将过去的信息传递到未来。

hₜ = tanh(Wₕh · hₜ₋₁ + Wₓh · xₜ + bₕ)   |   yₜ = Wₕᵧ · hₜ + bᵧ
RNN 展开结构图(Unrolled RNN)
x₁
t=1
A
h₁
隐藏层
x₂
t=2
A
h₂
隐藏层
x₃
t=3
A
h₃
隐藏层
y₃
输出

每个 A 单元接收当前输入 xₜ 和上一步的隐藏状态 hₜ₋₁,输出新的 hₜ。
虚线(水平方向)表示时间步之间的信息传递,即 RNN 的"记忆"。

4.2 基本 RNN 的致命缺陷

⚠️ 梯度消失问题在 RNN 中尤为严重 由于 RNN 在每个时间步都共享同一组权重矩阵,反向传播时梯度需要连续乘以相同的矩阵 T 次(T 为序列长度)。如果矩阵的最大特征值小于 1,梯度以指数速度衰减——这意味着 RNN 实际上无法学习长距离依赖
∂L/∂h₁ = ∂L/∂hₜ · ∏ₖ₌₂ᵀ ∂hₖ/∂hₖ₋₁ ← 当 T 很大时,连乘项趋近于 0

4.3 LSTM:长短期记忆网络 (1997)

1997 年,Sepp Hochreiter 和 Jürgen Schmidhuber 提出了 LSTM (Long Short-Term Memory) [5],通过精巧的门控机制 (Gating Mechanism)解决了梯度消失问题。

🚪 LSTM 的三个门

遗忘门 (Forget Gate)

决定从细胞状态中丢弃哪些信息。

fₜ = σ(Wf·[hₜ₋₁, xₜ] + bf)

输出 0~1,0 = 完全遗忘,1 = 完全保留

输入门 (Input Gate)

决定将哪些新信息写入细胞状态。

iₜ = σ(Wi·[hₜ₋₁, xₜ] + bi)

配合候选值 C̃ₜ,更新细胞状态

输出门 (Output Gate)

决定细胞状态中哪些部分作为当前输出

oₜ = σ(Wo·[hₜ₋₁, xₜ] + bo)

hₜ = oₜ · tanh(Cₜ)

Cₜ = fₜ ⊙ Cₜ₋₁ + iₜ ⊙ C̃ₜ    ← 细胞状态更新(核心公式)
✅ 为什么 LSTM 能解决梯度消失? 细胞状态 Cₜ 的更新是加法而非乘法(Cₜ = fₜ⊙Cₜ₋₁ + ...),当遗忘门 fₜ 接近 1 时,梯度可以几乎无损地流过长距离。信息可以在细胞状态中"直线传递",不经过多次矩阵乘法。

4.4 GRU:更简洁的 LSTM (2014)

2014 年,Kyunghyun Cho 等人提出了 GRU (Gated Recurrent Unit),将 LSTM 的遗忘门和输入门合并为一个更新门 (Update Gate),参数量减少约 25%,训练更快,效果相当。

LSTM

  • 3 个门:遗忘门 + 输入门 + 输出门
  • 2 个状态:隐藏状态 hₜ + 细胞状态 Cₜ
  • 参数量多,表达能力更强

GRU

  • 2 个门:重置门 + 更新门
  • 1 个状态:隐藏状态 hₜ
  • 参数少、训练快,效果接近 LSTM

4.5 RNN 的典型应用

应用领域任务代表模型/系统
机器翻译Seq2Seq 翻译Google Neural Machine Translation (GNMT)
语音识别语音转文字Deep Speech (Baidu), Kaldi
文本生成语言建模Char-RNN (Karpathy), LSTM-LM
情感分析文本分类Bidirectional LSTM
时序预测股票/天气LSTM 回归模型

👁️ 五、Attention 注意力机制

5.1 为什么需要 Attention?

Seq2Seq 模型使用编码器-解码器架构:编码器将整个输入序列压缩为一个固定长度的向量(上下文向量),解码器根据这个向量生成输出。

⚠️ 瓶颈问题 无论输入序列多长,编码器都必须将其压缩为一个固定长度的向量。当输入很长时,这个向量成为信息瓶颈——大量细节信息丢失。此外,解码器在每个时间步都只能看到同一个上下文向量,无法"聚焦"于输入的不同部分。

5.2 Seq2Seq + Attention (2015 Bahdanau)

2015 年,Dzmitry Bahdanau 等人提出了突破性的Additive Attention [6]。核心思想:解码器在每个时间步动态关注输入序列的不同部分,而非依赖一个固定的上下文向量。

📐 Attention 机制的三步计算

Step 1 — 计算对齐分数 (Alignment Score):衡量解码器的当前状态与编码器每个隐藏状态的相关性。

eₜᵢ = score(hₜ, h̄ᵢ) ← 可以是点积、加性等

Step 2 — 计算注意力权重 (Attention Weights):通过 Softmax 归一化为概率分布。

αₜᵢ = softmax(eₜᵢ) = exp(eₜᵢ) / Σⱼ exp(eₜⱼ)

Step 3 — 计算上下文向量 (Context Vector):加权求和得到当前时间步的上下文。

cₜ = Σᵢ αₜᵢ · h̄ᵢ ← 动态的上下文,每步都不同!
💡 直觉理解 想象你在翻译一句话 "The cat sat on the mat"。当翻译 "猫" 时,你的注意力集中在 "cat" 上(α 接近 1),而 "the"、"sat" 等词的注意力权重很低。Attention 机制让模型学会了这种"聚焦"能力。

5.3 Self-Attention:序列内部的自注意力

2017 年,Transformer 论文 [7] 将 Attention 的思想推向了一个新的高度:Self-Attention 不再局限于编码器和解码器之间,而是让序列中的每个元素都"注意"序列中的其他元素。

🔄 Self-Attention 的核心公式

每个 token 被映射为三个向量:Query (Q)Key (K)Value (V)

Attention(Q, K, V) = softmax(QKᵀ / √dₖ) · V

直觉类比——图书馆检索

  • Query = 你的搜索关键词
  • Key = 每本书的标签/标题
  • Value = 书的内容
  • 点积 QKᵀ = 关键词和标签的匹配度
  • Softmax = 归一化为注意力分布
  • 加权求和 V = 你最终获取的信息

5.4 从 Attention 到 Transformer 的跃迁

🚀 关键洞察 如果 Self-Attention 这么强大,那为什么还需要 RNN?

Vaswani 等人 2017 年的论文 "Attention Is All You Need" [7] 给出了震撼的答案:不需要 RNN 了。纯 Self-Attention 架构的 Transformer 具有以下优势:
  • 并行计算:不像 RNN 必须顺序计算,Self-Attention 可以同时处理所有位置
  • 长距离依赖:任意两个 token 之间的路径长度为 O(1),不像 RNN 是 O(n)
  • 更好的性能:在机器翻译等任务上全面超越 RNN

这个架构后来成为了 GPT、BERT、T5、PaLM 等所有大语言模型的基石——我们将在 PAGE 03: Transformer 架构 中深入拆解。

🚀 六、深度学习的突破性应用

♟️ AlphaGo (2016)

Google DeepMind | 强化学习 + 深度学习

2016 年 3 月,AlphaGo 以 4:1 击败世界围棋冠军李世石,震惊全球。围棋的搜索空间约为 10¹⁷⁰(宇宙原子数约 10⁸⁰),远超国际象棋。

核心技术

  • 策略网络 (Policy Network):用 CNN 预测下一步落子概率
  • 价值网络 (Value Network):评估当前局面的胜率
  • 蒙特卡洛树搜索 (MCTS):结合两种网络的评估进行搜索
  • 先用人类棋谱训练,再通过自我对弈强化学习提升

参考资料:Silver, D. et al. (2016). "Mastering the game of Go with deep neural networks and tree search." Nature.

🧬 AlphaFold (2020/2021)

Google DeepMind | 蛋白质结构预测

蛋白质的三维结构决定了其功能。AlphaFold 2 在 CASP14 竞赛中,以原子级精度预测蛋白质结构,GDT 分数达到 92.4(超过实验方法)。

核心技术

  • Evoformer:基于 Attention 的特征提取
  • 结构模块:迭代预测 3D 坐标
  • 多序列比对 (MSA):利用进化信息
  • 2021 年公开预测了 2 亿+ 蛋白质结构

参考资料:Jumper, J. et al. (2021). "Highly accurate protein structure prediction with AlphaFold." Nature.

🎨 AI 绘画:DALL-E / Stable Diffusion / Midjourney

OpenAI / Stability AI / Midjourney | 文本生成图像

DALL-E (2021)

OpenAI 首个文本生成图像模型,基于离散 VAE,证明了语言-视觉联合生成的可行性。

DALL-E 2 (2022)

使用 CLIP + 扩散模型 (Diffusion),图像质量和语义理解大幅提升。

Stable Diffusion (2022)

Stability AI 开源,在潜空间 (Latent Space) 中进行扩散,计算成本远低于像素空间。推动了 AI 绘画的民主化。

💡 扩散模型 (Diffusion Model) 的核心思想 前向过程逐步向图像添加高斯噪声,直到变成纯噪声;反向过程训练一个神经网络学习如何一步步去噪。训练目标:预测每一步添加的噪声。
L = E[||ε − εθ(xₜ, t)||²] ← 让模型预测添加的噪声 ε

💻 七、Python 代码示例

用 PyTorch 构建多层感知机 (MLP)

以下代码展示如何用 PyTorch 从零构建一个完整的 MLP,包括数据准备、模型定义、训练循环和评估。

Python · PyTorch MLP
"""
PyTorch 多层感知机 (MLP) 完整示例
任务:MNIST 手写数字分类 (10 分类)
结构:784 → 256 → 128 → 10
"""

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms


# ─── 1. 超参数设置 ───
BATCH_SIZE = 64          # 每个 mini-batch 的样本数
LEARNING_RATE = 0.001     # 学习率 (Adam 优化器的默认值)
EPOCHS = 10               # 训练轮次
HIDDEN_DIMS = [256, 128]  # 隐藏层维度列表
DROPOUT_RATE = 0.2        # Dropout 概率
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")


# ─── 2. 数据准备 ───
# 定义数据变换:将图像展平为向量并归一化
transform = transforms.Compose([
    transforms.ToTensor(),                      # PIL Image → Tensor (0~1)
    transforms.Normalize((0.1307,), (0.3081,)),     # 标准化 (MNIST 均值/标准差)
    transforms.Lambda(lambda x: x.view(-1)),          # 展平为 784 维向量
])

# 下载 MNIST 数据集
train_dataset = datasets.MNIST(
    root="./data", train=True, download=True, transform=transform
)
test_dataset = datasets.MNIST(
    root="./data", train=False, download=True, transform=transform
)

# 创建数据加载器 (自动 shuffle 和 batching)
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)

print(f"训练集大小: {len(train_dataset)} 样本")
print(f"测试集大小: {len(test_dataset)} 样本")
print(f"使用设备: {DEVICE")


# ─── 3. 定义 MLP 模型 ───
class MLP(nn.Module):
    """
    多层感知机 (Multi-Layer Perceptron)
    结构: 输入层(784) → 隐藏层1(256) → ReLU → Dropout →
          隐藏层2(128) → ReLU → Dropout → 输出层(10)
    """

    def __init__(self, input_dim, hidden_dims, output_dim, dropout_rate):
        super().__init__()
        layers = []

        # 构建隐藏层
        prev_dim = input_dim
        for hidden_dim in hidden_dims:
            layers.extend([
                nn.Linear(prev_dim, hidden_dim),  # 全连接层
                nn.ReLU(),                       # ReLU 激活函数
                nn.Dropout(dropout_rate),          # Dropout 正则化
            ])
            prev_dim = hidden_dim

        # 输出层 (不需要激活函数,CrossEntropyLoss 内含 Softmax)
        layers.append(nn.Linear(prev_dim, output_dim))

        self.network = nn.Sequential(*layers)

    def forward(self, x):
        """前向传播"""
        return self.network(x)


# 实例化模型
model = MLP(
    input_dim=28 * 28,              # MNIST 图像 28x28 = 784
    hidden_dims=HIDDEN_DIMS,      # [256, 128]
    output_dim=10,                 # 10 个数字类别
    dropout_rate=DROPOUT_RATE,
).to(DEVICE)

print(f"\n模型结构:\n{model}\n")


# ─── 4. 定义损失函数和优化器 ───
criterion = nn.CrossEntropyLoss()             # 交叉熵损失 (含 Softmax)
optimizer = optim.AdamW(                       # AdamW 优化器
    model.parameters(),
    lr=LEARNING_RATE,
    weight_decay=1e-4,                     # L2 正则化 (权重衰减)
)


# ─── 5. 训练循环 ───
def train(model, loader, criterion, optimizer):
    """训练一个 epoch"""
    model.train()           # 设置为训练模式 (启用 Dropout)
    total_loss = 0
    correct = 0
    total = 0

    for batch_idx, (data, target) in enumerate(loader):
        data, target = data.to(DEVICE), target.to(DEVICE)

        # 前向传播
        output = model(data)
        loss = criterion(output, target)

        # 反向传播 + 参数更新
        optimizer.zero_grad()   # 清除上一步的梯度
        loss.backward()        # 反向传播计算梯度
        optimizer.step()        # 根据梯度更新参数

        # 统计
        total_loss += loss.item()
        _, predicted = output.max(1)
        total += target.size(0)
        correct += predicted.eq(target).sum().item()

    avg_loss = total_loss / len(loader)
    accuracy = 100.0 * correct / total
    return avg_loss, accuracy


# ─── 6. 评估函数 ───
def evaluate(model, loader, criterion):
    """评估模型性能"""
    model.eval()            # 设置为评估模式 (关闭 Dropout)
    total_loss = 0
    correct = 0
    total = 0

    with torch.no_grad():   # 不计算梯度 (节省内存 + 加速)
        for data, target in loader:
            data, target = data.to(DEVICE), target.to(DEVICE)
            output = model(data)
            loss = criterion(output, target)

            total_loss += loss.item()
            _, predicted = output.max(1)
            total += target.size(0)
            correct += predicted.eq(target).sum().item()

    avg_loss = total_loss / len(loader)
    accuracy = 100.0 * correct / total
    return avg_loss, accuracy


# ─── 7. 开始训练 ───
print("="*50)
print("开始训练 MLP 模型...")
print("="*50))

for epoch in range(1, EPOCHS + 1):
    train_loss, train_acc = train(model, train_loader, criterion, optimizer)
    test_loss, test_acc = evaluate(model, test_loader, criterion)

    print(
        f"Epoch [{epoch}/{EPOCHS}] "
        f"训练 - Loss: {train_loss:.4f, Acc: {train_acc:.2f% | "
        f"测试 - Loss: {test_loss:.4f, Acc: {test_acc:.2f%"
    )

print("="*50)
print(f"训练完成! 最终测试准确率: {test_acc:.2f%")
print("="*50))
💡 代码要点解析
  • nn.Sequential:简化网络构建,自动串联各层
  • model.train() / model.eval():切换训练/评估模式,控制 Dropout 和 BatchNorm 的行为
  • torch.no_grad():评估时关闭梯度计算,减少内存占用并加速
  • optimizer.zero_grad():每步训练前清除旧梯度,防止梯度累积
  • AdamW:解耦的权重衰减优化器,Transformer 训练标配

期望结果:10 个 epoch 后测试准确率约 97-98%

📚 参考文献

  1. [1] McCulloch, W. S. & Pitts, W. (1943). "A logical calculus of the ideas immanent in nervous activity." Bulletin of Mathematical Biophysics, 5(4), 115-133.
  2. [2] Rumelhart, D. E., Hinton, G. E. & Williams, R. J. (1986). "Learning representations by back-propagating errors." Nature, 323, 533-536.
  3. [3] LeCun, Y., Bottou, L., Bengio, Y. & Haffner, P. (1998). "Gradient-based learning applied to document recognition." Proceedings of the IEEE, 86(11), 2278-2324.
  4. [4] Krizhevsky, A., Sutskever, I. & Hinton, G. E. (2012). "ImageNet Classification with Deep Convolutional Neural Networks." NeurIPS 2012. (aka "AlexNet")
  5. [5] Hochreiter, S. & Schmidhuber, J. (1997). "Long Short-Term Memory." Neural Computation, 9(8), 1735-1780.
  6. [6] Bahdanau, D., Cho, K. & Bengio, Y. (2015). "Neural Machine Translation by Jointly Learning to Align and Translate." ICLR 2015.
  7. [7] Vaswani, A. et al. (2017). "Attention Is All You Need." NeurIPS 2017.
  8. [8] Goodfellow, I., Bengio, Y. & Courville, A. (2016). Deep Learning. MIT Press. deeplearningbook.org
  9. [9] LeCun, Y., Bengio, Y. & Hinton, G. (2015). "Deep learning." Nature, 521, 436-444.
  10. [10] Kingma, D. P. & Ba, J. (2015). "Adam: A Method for Stochastic Optimization." ICLR 2015.
  11. [11] He, K. et al. (2016). "Deep Residual Learning for Image Recognition." CVPR 2016. (ResNet)
  12. [12] Loshchilov, I. & Hutter, F. (2019). "Decoupled Weight Decay Regularization." ICLR 2019. (AdamW)