Skip to content

第4章 卷积神经网络 — 让网络"看见"图像

Chapter 4: Convolutional Neural Networks — Teaching Networks to "See" Images

卷积(convolution /ˌkɒnvəˈluːʃən/)神经网络(Convolutional Neural Network, CNN) 是深度学习在计算机视觉领域取得突破性进展的核(kernel /ˈkɜːrnl/)心引擎。从手写数字识别到自动驾驶,从医疗影像诊断到人脸识别,CNN 无处不在。本章将深入卷积操作的数学本质,理解 CNN 为何天生适合图像,并沿着经典架构的演进路线,一步步走向现代 CNN 设计思想。

时间线:

  • 1989: LeCun 提出卷积神经网络(CNN)
  • 1998: LeCun et al. 提出 LeNet-5
  • 2012: AlexNet 赢得 ImageNet 竞赛,深度学习革命开始
  • 2015: He et al. 提出 ResNet(残差网络)

CNNs are the engine behind deep learning's breakthrough in computer vision. From handwritten digit recognition to autonomous driving, from medical imaging to face recognition, CNNs are everywhere. This chapter dives into the mathematics of convolution, explains why CNNs are inherently suited for images, and traces the evolution from LeNet to modern ConvNeXt.

前置知识 (Prerequisites): 第3章(线性模型、神经网络基础),微积分(积分、偏导数),线性代数(矩阵运算) 依赖库 (Dependencies): torch>=2.1.0, torchvision>=0.16.0, matplotlib>=3.7.0, numpy>=1.24.0

Code companion: code/cnn_cifar10.py — 实际输出见文末附录


目录 (Table of Contents)

  1. 卷积运算的数学定义 📐 1.3 关键参数 (Key Parameters) 📐
  2. 为什么 CNN 适合图像
  3. 池化(pooling /ˈpuːlɪŋ/) (Pooling)
  4. 经典架构演进
  5. 小结 (Summary)

1. 卷积运算的数学定义 (Mathematical Definition of Convolution)

1.1 从连续到离散 (From Continuous to Discrete)

卷积(Convolution)是一个在数学、信号处理和深度学习中都极其重要的运算。它的核心思想是:用一个函数(核/滤波器)去"扫描"另一个函数,在每一点上计算加权和

连续定义 (Continuous Definition):

两个连续函数 fg 的卷积定义为:

(fg)(t)=f(τ)g(tτ)dτ

其中 表示卷积运算符。直观理解:g 是一个"模板",翻转后滑过 f,在每个位置 t 上计算重叠区域的加权积分。

离散定义 (Discrete Definition):

在计算机中,信号是离散的。对于一维离散信号 f 和核 g

(fg)[n]=m=f[m]g[nm]

1.2 二维离散卷积 (2D Discrete Convolution)

在图像处理中,输入是二维矩阵 I(图像),核是二维矩阵 K(kernel/filter)。二维离散卷积定义为:

S(i,j)=(IK)(i,j)=mnI(i+m,j+n)K(m,n)

其中 S(i,j) 是输出特征图(feature map)在位置 (i,j) 的值。

💡 直观理解:K 看作一个"窗口",它在 I 上逐像素滑动。在每个位置,窗口内的像素值与核的对应权重相乘后求和,得到一个输出值。这个输出值表示"核模板"在当前窗口位置的匹配程度。

1.3 关键参数 (Key Parameters)

参数(parameter /pəˈræmɪtər/)符号含义公式
核大小k卷积窗口的尺寸(如 3×3
步长s核每次滑动的像素数
填充p输入边缘补零的圈数
扩张d核元素之间的间隔

输出尺寸公式:

给定输入尺寸 Win,核尺寸 k,步长 s,填充 p,扩张 d,输出尺寸为:

Wout=Win+2pd(k1)1s+1

常见的填充模式:

  • Valid 卷积 (无填充): p=0,输出尺寸减小
  • Same 卷积: p=k12k 为奇数),输出尺寸与输入相同
  • Full 卷积: p=k1,输出尺寸增大

💡 直觉: 可以把 kernel 想象成一个"特征探测器"。比如一个 3×3 的核,如果中间列全是正数、两边全是负数,它就会对垂直边缘有强烈响应。不同的核权重对应检测不同的特征——边缘、纹理、颜色变化等。

🔍 完整演算:输出尺寸公式验证 — 多参数组合手算

📐 公式

卷积输出尺寸的通用公式(包含扩张 dilation):

Wout=Win+2pd(k1)1s+1

当扩张 d=1(最常见情况)时,公式简化为:

Wout=Win+2pks+1

📖 参数含义

符号名称含义
Win输入尺寸 (Input Size)输入特征图的宽度(或高度)
k核尺寸 (Kernel Size)卷积核的宽度(假设正方形核)
s步长 (Stride)核每次滑动的像素数
p填充 (Padding)输入边缘补零的圈数
d扩张 (Dilation)核元素之间的间隔,d=1 表示标准核
向下取整 (Floor)结果必须是整数,不能有半个像素

📝 公式来源

公式的直观含义:计算核能在输入上滑动多少次。

核覆盖的有效宽度为 k+(k1)(d1)=d(k1)+1。输入在填充后的有效宽度为 Win+2p。核从最左侧滑到最右侧,可滑动的总距离为 (Win+2p)(d(k1)+1)。以步长 s 滑动,滑动次数为 Win+2pd(k1)1s,加上起始位置即为输出尺寸。


✏️ 手算演示

以下用 Win=28(如 MNIST 手写数字图像)验证三种常见参数组合。

例 1: Valid 卷积(无填充)

参数:Win=28, k=3, s=1, p=0

Wout=28+2(0)31+1=25+1=26

输出 26×26。每个卷积步骤后,特征图缩小了 2 个像素(因为 3×3 核不能在边缘处完整放置)。

验证: 核在 28×28 上以步长 1 滑动,可放置的起始位置为 0,1,2,,25,共 26 个位置。✓


例 2: 步长为 2 的下采样

参数:Win=28, k=3, s=2, p=0

Wout=28+2(0)32+1=12.5+1=13.5=13

输出 13×13,尺寸约为输入的一半。步长 2 的卷积常用于替代池化层进行下采样。

验证: 核以步长 2 滑动,起始位置为 0,2,4,,24,共 13 个位置。✓


例 3: Same 卷积(保持尺寸)

参数:Win=28, k=3, s=1, p=1

Wout=28+2(1)31+1=27+1=28

输出 28×28,与输入尺寸相同。对于 k=3 的奇数核,p=1 恰好使得输出尺寸不变——这就是 Same 卷积的填充策略 p=k12

验证: 填充 1 圈零后,输入变为 30×30。核在 30×30 上以步长 1 滑动,起始位置 0,1,,27,共 28 个。✓


总结对比

WinkspWout效果
12831026Valid 卷积,尺寸缩小
22832013步长为 2,下采样至约一半
32831128Same 卷积,尺寸不变

🌍 实际意义

  • 设计网络时,输出尺寸公式是 CNN 架构设计的基础工具。每一层的 Wout 决定了下一层的输入尺寸,影响着参数量和感受野的覆盖范围。
  • 下采样策略:步长 2 的卷积(WoutWin/2)是现代 CNN 中替代池化层的常用下采样方式,如 ResNet、ConvNeXt 等架构均采用此设计。
  • Same 卷积:通过 p=k12 保持特征图尺寸不变,使得网络可以堆叠任意深度的卷积层。这是 VGG、ResNet 等架构大量使用 3×3 核加 p=1 的原因。
  • 自动推导:理解公式后,给定任意参数组合都能快速算出输出尺寸,避免编码时的维度错误。
🔍 完整演算:卷积核手算 — 3×3 核在 5×5 输入上的滑动过程

📐 公式

二维离散卷积定义:

S(i,j)=(IK)(i,j)=m=0kh1n=0kw1I(i+m,j+n)K(m,n)

其中 I 为输入图像,K 为卷积核,S 为输出特征图。


📖 参数含义

符号名称含义
K卷积核 / 滤波器 (Kernel/Filter)可学习的特征探测器,本例为 3×3 矩阵
S输出特征图 (Output Feature Map)卷积操作后得到的二维激活图
I输入 (Input)待卷积的输入数据,本例为 5×5 矩阵
stride s步长 (Stride)核每次滑动的像素数,本例 s=1
padding p填充 (Padding)输入边缘补零的圈数,本例 p=0

📝 公式来源

二维离散卷积直接来自连续卷积的离散化。在信号处理中,卷积 (fg)(t)=f(τ)g(tτ)dτ 表示一个函数翻转后滑过另一个函数。在图像处理中,核通常不需要翻转(严格来说是互相关 cross-correlation,但深度学习领域常混称为卷积),直接在输入上滑动计算加权和。

S(i,j)=mnI(i+m,j+n)K(m,n)

本例中 0i2, 0j2,因为输出尺寸 Wout=53+1=3


✏️ 手算演示

给定 5×5 输入矩阵 I3×3 边缘检测核 K

I=[1010101010101010101010101]K=[111181111]

K 是一个拉普拉斯(Laplacian)边缘检测核:中心为正、周围为负,对局部灰度变化敏感。

Step 1: 核在左上角 (i=0,j=0) 位置

核覆盖的区域为 I[0:2,0:2]

I00=[101010101]

对应元素相乘:

S(0,0)=(1)(1)+(0)(1)+(1)(1)+(0)(1)+(1)(8)+(0)(1)+(1)(1)+(0)(1)+(1)(1)=1+01+0+8+01+01=4

Step 2: 核向右滑动一步 (i=0,j=1)

核覆盖 I[0:2,1:3]

I01=[010101010]

对应元素相乘:

S(0,1)=(0)(1)+(1)(1)+(0)(1)+(1)(1)+(0)(8)+(1)(1)+(0)(1)+(1)(1)+(0)(1)=01+01+01+01+0=4

Step 3: 核向下滑动一步 (i=1,j=0)

核覆盖 I[1:3,0:2]

I10=[010101010]

与 Step 2 相同的对称位置,结果也相同:

S(1,0)=4

Step 4: 完整输出特征图

按此方式计算所有 3×3=9 个位置,得到输出特征图:

S=[444444444]

输出尺寸为 3×3,验证了 Wout=53+1=3


🌍 实际意义

  • 边缘检测:卷积核的权重模式决定了它检测的特征类型。本例中的拉普拉斯核对局部亮度变化敏感——当核覆盖区域中心与周围差异大时,输出值大;反之输出值接近 0。
  • 从低级到高级:浅层卷积核检测边缘、纹理等低级特征;中层卷积核检测形状、部件;深层卷积核检测物体、场景等高级语义特征。
  • 可学习性:在 CNN 训练中,卷积核的权重不是手工设计的,而是通过反向传播从数据中自动学习得到的,使网络能针对特定任务发现最优特征探测器。
  • 参数共享优势:同一个 3×3 核(仅 9 个参数)扫描整个 5×5 输入,无论特征出现在哪个位置,都能被同一个探测器识别。

2. 为什么 CNN 适合图像 (Why CNNs are Suited for Images)

CNN 之所以在图像上取得巨大成功,源于三个关键设计原则。这些原则利用了自然图像的固有结构

2.1 局部连接 (Local Connectivity)

在传统的全连接网络(Fully Connected Network)中,每个输出神经元与所有输入神经元相连。而在 CNN 中,每个输出神经元只连接到输入的一个局部区域(感受野, receptive field)。

直觉: 自然图像中,相邻像素之间的相关性远高于远距离像素。你不需要看整张图就能识别一个边缘或一个角点——局部信息就足够了。

参数量的对比:

  • 全连接层:每个输出神经元有 Cin×Win×Hin 个连接
  • 卷积层:每个输出神经元有 k×k×Cin 个连接

对于一张 224×224 的 RGB 图像,一个 3×3 卷积的感受野只需要 3×3×3=27 个连接,而全连接需要 224×224×3=150,528 个连接。

2.2 参数共享 (Parameter Sharing)

CNN 中,同一个核会在输入的所有位置上共享相同的权重。这意味着无论特征出现在图像的哪个位置,同一个探测器都能检测到它。

直觉: 一个垂直边缘检测器在图像左上角有用,在右下角也同样有用。我们不需要为每个位置学习独立的探测器。

参数量的巨大差异:

对于输入 RCin×H×W 和输出 RCout×H×W

  • 全连接层: O(CinHWCout) 个参数
  • 卷积层: O(k2CinCout) 个参数

对于 224×224 图像,3×3 卷积,64 个输出通道:

层类型参数数量比例
全连接层2242×3×649.6×106107
卷积层32×3×64=1,728103

参数共享将参数量降低了约 5000 倍!

2.3 平移等变性 (Translation Equivariance)

如果输入图像平移了几个像素,特征图也会相应地平移几个像素。这一性质被称为平移等变性

Tx(IK)=(TxI)K

其中 Tx 表示平移操作。

直觉: 猫无论出现在图像的左上角还是右下角,CNN 都能检测到它。全连接网络需要从训练数据中"记住"猫在不同位置的特征,而 CNN 通过卷积操作天然获得了这一能力。

2.4 对比总结 (Summary Comparison)

性质全连接层卷积层
连接方式全局连接局部连接(感受野)
参数共享❌ 每个位置独立参数✅ 全局共享
平移等变性❌ 需要数据增强学习✅ 天然具备
参数数量(224264 特征图)O(107)O(103)
对空间结构的利用❌ 展平为向量✅ 保持 2D 结构

3. 池化 (Pooling)

池化层是 CNN 中另一个核心组件,它通过下采样来降低特征图的空间维度。

3.1 最大池化 (Max Pooling)

2×2 的窗口内取最大值:

输入特征图:            输出 (2×2 Max Pooling):
[1, 3, 2, 4]          [3, 4]
[5, 6, 7, 8]    →     [6, 8]
[9, 1, 2, 3]
[4, 5, 6, 7]

3.2 平均池化 (Average Pooling)

2×2 的窗口内取平均值:

输入特征图:            输出 (2×2 Avg Pooling):
[1, 3, 2, 4]          [3.75, 5.25]
[5, 6, 7, 8]    →     [4.75, 4.50]
[9, 1, 2, 3]
[4, 5, 6, 7]

3.3 为什么需要池化?

1. 降低维度 (Dimensionality Reduction)

池化将特征图的宽高减半,参数量和计算量随之降低为原来的 14

2. 平移不变性 (Translation Invariance)

池化使得输出对微小平移不敏感。想象一个 2×2 的最大池化:特征向右平移 1 个像素后,最大池化的输出可能完全不变。

💡 区分等变 vs. 不变: 卷积提供平移等变性(特征位置随输入变化),池化提供平移不变性(对微小平移不敏感)。等变性有助于定位,不变性有助于识别。

3. 增大感受野

每一步池化都让后续卷积层的感受野扩大一倍,使网络能捕捉更大范围的上下文信息。

3.4 池化 vs. 步长卷积

现代 CNN 设计中,池化层越来越多地被步长卷积(strided convolution)替代,因为:

  • 步长卷积的参数是可学习的,而池化无参数
  • 步长卷积可以与卷积层融合,减少层数

4. 经典架构演进 (Architecture Evolution)

CNN 从 1998 年的 LeNet 到今天的 ConvNeXt,经历了近 25 年的演进。理解这条演进路线,就是理解深度学习视觉领域的设计哲学演变

mermaid
flowchart LR
    LeNet[LeNet 1998] -->|"更大更深"| AlexNet[AlexNet 2012]
    AlexNet -->|"更规整"| VGG[VGG 2014]
    VGG -->|"残差连接"| ResNet[ResNet 2015]
    ResNet -->|"复合缩放"| EfficientNet[EfficientNet 2019]
    ResNet -->|"现代化改造"| ConvNeXt[ConvNeXt 2022]

4.1 LeNet-5 (1998) — 开山之作

由 Yann LeCun 于 1998 年提出,用于手写数字识别(MNIST)。

结构: Conv(5×5) → Pool(2×2) → Conv(5×5) → Pool(2×2) → FC(120) → FC(84) → FC(10)

关键点:

  • 确立了 CNN 的基本范式:卷积 → 池化 → 卷积 → 池化 → 全连接
  • 输入 32×32 灰度图
  • 使用 5×5 卷积核和 2×2 平均池化

4.2 AlexNet (2012) — 深度学习革命

由 Alex Krizhevsky 于 2012 年提出,在 ImageNet 上以巨大优势夺冠,标志着深度学习时代的到来。

关键创新:

  • ReLU 激活函数: f(x)=max(0,x),解决了饱和激活函数的梯度(gradient /ˈɡreɪdiənt/)消失问题
  • Dropout(/ˈdrɒpaʊt/): 随机(stochastic /stəˈkæstɪk/)丢弃神经元,防止过拟合(overfitting /ˈoʊvərˈfɪtɪŋ/)
  • 数据增强: 随机裁剪、水平翻转、颜色变换
  • GPU 训练: 使用两块 GTX 580 GPU 并行训练

为什么 ReLU 比 Sigmoid(/ˈsɪɡmɔɪd/)/Tanh 好?

Sigmoid: σ(x)=11+ex梯度: σ(x)0.25ReLU: f(x)=max(0,x)梯度: 1 (当 x>0)

ReLU 在正半轴的梯度恒为 1,不会出现梯度消失。这使得训练更深的网络成为可能。

4.3 VGG (2014) — 简洁的力量

由牛津大学 Visual Geometry Group 提出,证明了深度而非单个层的复杂度更重要。

核心设计:

  • 全部使用 3×3 卷积核
  • 全部使用 2×2 最大池化
  • 堆叠多个 3×3 卷积,替代更大的核

为什么堆叠 3×3 比单个 5×5 更好?

堆叠两个 3×3 卷积(无池化)的感受野等于一个 5×5 卷积:

  • 参数量:2×(3×3×C2)=18C2 vs. 5×5×C2=25C2
  • 更少的参数 + 更多的非线性(两次 ReLU)= 更强的表示能力

VGG 将网络深度推到了 16-19 层,但也暴露了一个问题:超过一定层数后,单纯的堆叠不再带来精度提升

4.4 ResNet (2015) — 残差学习的革命

ResNet(Residual Network)由 Kaiming He 等人于 2015 年提出,是 CNN 发展史上最重要的里程碑之一。它解决了网络退化(Degradation) 问题,使得训练上百层的网络成为可能。

4.4.1 退化问题 (The Degradation Problem)

直觉告诉我们:更深的网络应该能取得更好的性能。但实验发现,当网络层数增加到一定程度后,训练误差反而上升。这不是过拟合(测试误差也上升),而是一个优化问题——深层网络更难优化。

浅层网络: Lshallowvs.深层网络: Ldeep>Lshallow

4.4.2 残差连接 (Skip Connection)

ResNet 的核心思想:不再学习原始的映射 H(x),而是学习残差映射 F(x)=H(x)x

H(x)=F(x)+x学习 F(x)=H(x)x

ResNet building block

        x


    ┌─────────┐
    │ Conv3×3 │
    │  ReLU   │
    │ Conv3×3 │
    └────┬────┘
         │ F(x)

    ┌─────────┐
    │   + ◄───│──── x (identity shortcut)
    └────┬────┘

        ReLU


       F(x) + x

4.4.3 为什么残差连接有效?

视角 1: 梯度流动

在前向传播中,信息可以沿着恒等捷径(identity shortcut)直接流动。在反向传播(backpropagation /ˌbækprəpəˈɡeɪʃən/)中,梯度也可以直接流过捷径,到达前层:

Lx=LHHx=LH(1+Fx)

梯度中有一个"1"项,确保梯度不会消失。即使 Fx0,梯度也能通过恒等路径传播。

视角 2: 学习目标更简单

假设网络已经接近最优,H(x)x。在传统网络中,层需要学习 H(x)=x(恒等映射),这对多层非线性堆叠来说是困难的。而在残差网络中,层只需要学习 F(x)0,即将残差推近到零——这比学习恒等映射容易得多。

视角 3: 网络集成 (Ensemble)

ResNet 可以被解释为多个浅层网络的隐式集成。因为捷径的存在,网络中的路径可以被"跳过",形成一个指数级数量的浅层子网络集合。

4.4.4 ResNet 系列架构

变体层数结构特点参数数量
ResNet-1818BasicBlock(2 层卷积)11M
ResNet-3434BasicBlock(2 层卷积)22M
ResNet-5050Bottleneck(1×1→3×3→1×1)26M
ResNet-101101Bottleneck45M
ResNet-152152Bottleneck60M

Bottleneck 设计:

对于更深的 ResNet(50+),使用 1×13×31×1 的 bottleneck 结构,通过 1×1 卷积先降维再升维,减少计算量:

256-d1×1,643×3,641×1,256

4.5 现代演进 (Modern Evolution)

EfficientNet (2019)

提出了复合缩放(Compound Scaling) 策略:同时缩放网络的深度、宽度和分辨率。通过 Neural Architecture Search (NAS) 找到最优缩放系数:

深度:d=αϕ,宽度:w=βϕ,分辨率:r=γϕ

其中 αβ2γ22(计算量约束),ϕ 是用户指定的缩放系数。

ConvNeXt (2022)

ConvNeXt 对 ResNet 进行"现代化改造",吸收了 Swin Transformer(/trænsˈfɔːrmər/) 的设计经验:

改造项ResNetConvNeXt效果
激活函数ReLUGELU更平滑的梯度
归一化(normalization /ˌnɔːrmələˈzeɪʃən/)BatchNormLayerNorm更好的稳定性
下采样MaxPool步长卷积可学习下采样
核大小3×37×7更大感受野
阶段设计堆叠倒置瓶颈更高效

ConvNeXt 证明:经过现代化改造的纯 CNN 架构,性能可以媲美 Vision Transformer。


本章演算盒索引

位置演算盒跳转
§1🔍 卷积核手算 — 3×3 核在 5×5 输入跳转
§1.3🔍 输出尺寸公式验证 — 多参数组合跳转

5. 小结 (Summary)

核心概念回顾

概念要点
卷积运算(IK)(i,j)=mnI(i+m,j+n)K(m,n),核是特征探测器
局部连接每个神经元只连接输入的局部区域,参数量从 O(n2) 降到 O(k2)
参数共享同一核滑动扫描全图,进一步降低参数量
平移等变性输入平移 → 特征图同步平移
池化最大池化/平均池化,降低维度,提供平移不变性
残差连接H(x)=F(x)+x,解决退化问题,使训练上百层网络成为可能

架构演进速览

LeNet (1998)     5 层    手写数字识别
AlexNet (2012)   8 层    ReLU + Dropout + GPU
VGG (2014)      16-19 层  全部 3×3 卷积
ResNet (2015)   18-152 层  残差连接 → 核心思想沿用至今
EfficientNet    2019    复合缩放
ConvNeXt        2022    纯 CNN 现代化改造

关键洞见

  1. CNN 的设计哲学是归纳偏置(inductive bias):利用图像的结构化特性(局部性、平移不变性、层次性),将这些先验知识编码到网络架构中。
  2. 残差连接是 CNN 最重要的贡献——它使训练极深网络成为可能,其思想(短路连接/捷径)后来被 Transformer 等架构广泛采用。
  3. CNN 在与 Transformer 的竞争中并未过时:ConvNeXt 等现代化 CNN 证明,经过合理改造的纯卷积架构仍然具有竞争力。

下一步: 运行代码实战 CNN on CIFAR-10,从零实现 ResNet 并在 CIFAR-10 上训练验证残差连接的效果。


附录: 实际运行输出 (Actual Runtime Output)

以下是在 CPU 上运行 cnn_cifar10.py --epochs 3 的实际控制台输出,展示了 ResNet-20 在 CIFAR-10 上的逐 epoch 训练过程:

$ .venv/bin/python ai/04-neural-networks/code/cnn_cifar10.py --epochs 3

Using device: cpu
============================================================
ResNet on CIFAR-10 -- Training Starting
============================================================
Device:        cpu
Epochs:        3
Batch size:    128
Learning rate: 0.1
Weight decay:  0.0005
Momentum:      0.9

[1/4] Loading data...
Train samples: 50000
Test samples:  10000
Batches per epoch (train): 391

[2/4] Building ResNet-20 model...
Total parameters:     272,474
Trainable parameters: 272,474
Model architecture:
ResNet(
  (conv1): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (bn1): BatchNorm2d(16, ...)
  (layer1): Sequential((0-2): 3× ResidualBlock(16→16, stride=1))
  (layer2): Sequential(
    (0): ResidualBlock(16→32, stride=2)  ← shortcut uses 1×1 conv
    (1-2): 2× ResidualBlock(32→32, stride=1)
  )
  (layer3): Sequential(
    (0): ResidualBlock(32→64, stride=2)  ← shortcut uses 1×1 conv
    (1-2): 2× ResidualBlock(64→64, stride=1)
  )
  (avg_pool): AdaptiveAvgPool2d((1, 1))
  (fc): Linear(64 → 10)
)

[3/4] Starting training...
--------------------------------------------------------------------------------
 Epoch |  Train Loss |  Train Acc |  Test Loss |  Test Acc |     Time
--------------------------------------------------------------------------------
     1 |      1.5459 |     42.11% |     1.4651 |    49.97% |   103.4s
  → Best model saved! (test_acc=49.97%)
     2 |      1.0691 |     61.60% |     0.9676 |    66.60% |   104.9s
  → Best model saved! (test_acc=66.60%)
     3 |      0.8730 |     69.18% |     0.8365 |    70.96% |   102.4s
  → Best model saved! (test_acc=70.96%)
--------------------------------------------------------------------------------
Training completed! Best test accuracy: 70.96%

[4/4] Plotting training curve...
Training curve saved to: output/training_curve.png
Final model saved to: output/resnet20_cifar10_final.pth
Done!

分析 (Analysis):

EpochTrain AccTest Acc观察
142.11%49.97%模型快速收敛,从随机初始化迅速学习基本特征
261.60%66.60%准确率跃升~17%,残差连接使梯度高效传播
369.18%70.96%训练与测试差距缩小(仅差 1.78pp),模型泛化能力良好

关键观察 (Key Observations):

  1. 快速收敛: 仅 3 个 epoch,测试准确率就达到了 70.96%。如果使用 GPU 训练更多 epoch(如 50-100),配合学习率衰减,ResNet-20 在 CIFAR-10 上可以轻松达到 91-93% 的测试准确率。
  2. 残差连接的有效性: ResNet-20 只有 272K 参数(约 0.27M),远小于 VGG-16 的 138M 参数,但性能相当。这说明残差连接显著提升了参数效率和梯度流动。
  3. 梯度流动顺畅: 与不包含残差连接的普通网络相比,ResNet 在训练初期就能快速降低损失(从 1.5459→0.8730),梯度可以高效地通过捷径传播到网络的前层。
  4. 训练/测试差距很小: 第 3 个 epoch 时,训练和测试准确率相差不到 2 个百分点,说明模型没有过拟合,仍有进一步提升空间。

参考文献 (References)

  1. LeCun, Y. et al. (1998). Gradient-based learning applied to document recognition. Proc. IEEE, 86(11), 2278–2324.
  2. Krizhevsky, A., Sutskever, I. & Hinton, G. E. (2012). ImageNet classification(/ˌklæsɪfɪˈkeɪʃən/) with deep convolutional neural networks. NeurIPS.
  3. He, K. et al. (2016). Deep residual learning for image recognition. CVPR.