第 6 章 卷积神经网络与视觉建模
6.1 学习目标
- 理解为什么图像任务适合使用卷积而不是纯全连接。
- 掌握卷积、池化、步幅、填充、感受野等核心概念。
- 理解经典 CNN 结构从 LeNet 到现代轻量网络的演化。
- 能搭建一个基础图像分类模型并完成训练。
- 理解卷积网络在特征提取、鲁棒性和参数效率上的优势。
能力矩阵:
| 能力域 | 入门 | 进阶 | 熟练 |
|---|---|---|---|
| 卷积概念 | 会看卷积层 | 理解卷积核和特征图 | 能推导输出尺寸 |
| 视觉任务 | 会做分类 | 会做增强与调参 | 能分析错误样本 |
| 结构设计 | 会堆 CNN | 会用 BatchNorm / Dropout | 能选轻量或深层结构 |
6.2 为什么需要卷积
图像天然具有局部相关性和平移不变性:
- 邻近像素更相关;
- 目标移动一点,不应完全改变识别结果;
- 全连接会引入大量参数,难以训练。
卷积通过局部连接和权值共享显著降低参数量。
6.3 卷积基础
6.3.1 卷积核
卷积核是一个可学习的小窗口,它在输入上滑动并提取局部特征。
6.3.2 输出尺寸
若输入宽高为 ,卷积核大小为 ,步幅为 ,填充为 ,则输出尺寸为:
6.3.3 感受野
感受野是输出神经元能够看到的输入区域。随着层数增加,感受野逐渐扩大。
6.4 池化
6.4.1 最大池化
取局部窗口中的最大值,用于降采样和提取显著特征。
6.4.2 平均池化
取局部窗口平均值,更平滑。
6.4.3 作用
- 降低空间分辨率
- 缓解计算量
- 增强一定的平移鲁棒性
6.5 典型 CNN 结构
6.5.1 经典流水线
Conv -> ReLU -> Pool -> Conv -> ReLU -> Pool -> Flatten -> FC -> FC -> Softmax6.5.2 LeNet 思路
早期 CNN 的基本思想是:
- 先提局部边缘与纹理;
- 再形成更高层语义;
- 最后输出分类结果。
6.5.3 现代 CNN 改进
常见改进包括:
- 更深的网络
- BatchNorm
- 残差连接
- 全局平均池化
- 深度可分离卷积
6.6 卷积网络的参数效率
全连接层参数量大约为:
卷积层参数量大约为:
当输入图像很大时,卷积层更节省参数。
6.7 视觉任务中的训练技巧
6.7.1 数据增强
常见增强:
- 随机翻转
- 随机裁剪
- 颜色抖动
- Cutout
- Mixup
6.7.2 归一化
图像通常按通道做标准化,常见做法是减均值除方差。
6.7.3 迁移学习
如果数据少,可从预训练模型开始微调,而不是完全从零训练。
6.8 PyTorch 结构示例
import torchimport torch.nn as nn
class SimpleCNN(nn.Module): def __init__(self, num_classes=10): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(64 * 8 * 8, 128), nn.ReLU(), nn.Linear(128, num_classes), )
def forward(self, x): x = self.features(x) return self.classifier(x)6.9 CNN 的优势与局限
6.9.1 优势
- 参数共享
- 局部感知
- 平移鲁棒性
- 更适合二维网格结构数据
6.9.2 局限
- 对长程依赖建模较弱
- 对旋转、尺度变化不天然鲁棒
- 对非网格数据不够灵活
6.10 常见视觉任务
- 图像分类
- 目标检测
- 语义分割
- 实例分割
- 超分辨率
- 风格迁移
- 图像生成
6.11 典型错误排查
- 输入维度顺序不对。
- 忘记标准化或数据增强。
- 卷积输出尺寸算错。
- 最后一层分类数和标签数不一致。
- 学习率太高导致 loss 震荡。
- 过拟合但没有使用正则化。
6.12 本章小结
CNN 的核心不是“更复杂的层”,而是把视觉任务的结构先验编码进去。卷积、池化和多层堆叠让模型能更有效地从图像中提取局部到全局的特征。
6.13 课后练习
- 推导卷积输出尺寸公式。
- 比较全连接层和卷积层的参数量差异。
- 解释感受野是什么。
- 说明为什么图像任务特别适合卷积网络。
- 用 PyTorch 写一个简单 CNN 训练 MNIST 或 CIFAR-10。
6.14 卷积的数学细节与实现视角
卷积在数学上可以被视作对输入张量做局部加权求和。对二维输入 与卷积核 ,输出 的某一位置 为:
在工程实现上,常把卷积转化为矩阵乘法以便利用高效的 GEMM:这就是 im2col 技术。im2col 把滑动窗口展开为列矩阵,核张量展平为行矩阵,两者相乘即得输出。
优点:可以复用高度优化的矩阵乘法库(BLAS/CuBLAS)。缺点:内存占用上升且额外的重排开销。
6.14.1 im2col 示例(概念)
假设输入为单通道,卷积核大小为 ,im2col 会将每个 的局部块拉直为长度为 9 的向量,并把所有滑动窗口堆叠为一个矩阵 ;核张量同样被展平为 ,输出矩阵 。
6.14.2 卷积的复杂度
单层卷积的计算复杂度近似为:
这决定了设计时需在参数量、计算量与表达能力之间权衡。
6.15 卷积的反向传播(推导要点)
设前向计算为 (* 表示卷积),损失 对 的上游梯度为 。则梯度传播为:
- 对核的梯度:(其中 表示互相关或合适翻转后的卷积);
- 对输入的梯度:( 是核按空间维度翻转后的卷积)。
在 im2col 的实现下,反向传播可以转化为对矩阵乘法的转置操作,从而复用高速矩阵乘法接口。
工程实践要点:
- 注意步幅与填充在前向与反向传播中的一致性;
- group conv 会把
C_in和C_out分成若干组,反向传播要分别计算; - 深度可分离卷积的权重更新与普通卷积不同,需要分别对深度卷积和逐点卷积求梯度。
6.16 进阶卷积类型
6.16.1 深度可分离卷积(Depthwise Separable Conv)
由 Depthwise 卷积和 Pointwise (1x1) 卷积组成,显著减少参数与计算,MobileNet 等轻量网络常用。
参数量对比:假设 核,输入通道 ,输出通道 ,一般卷积参数为 ,深度可分离卷积参数为 ,当 小且 大时可节省大量参数。
6.16.2 空洞卷积(Dilated / Atrous Conv)
通过在卷积核中引入空洞率(dilation)来扩大感受野而不增加参数或降低分辨率,常用于语义分割(DeepLab 系列)。
6.16.3 组卷积(Group Conv)与稀疏连接
组卷积把通道分为若干组,组间不共享卷积核。它既减少计算,又能在某些架构中引入层间特定的结构(如 ResNeXt)。
6.16.4 反卷积(Transposed Conv)
用于上采样和生成模型中。需要注意步幅与填充的对应关系,以避免 checkerboard artifact(棋盘状伪影)。通常推荐使用上采样 + 卷积替代反卷积来降低伪影风险。
6.17 现代网络模块与设计模式
6.17.1 残差连接(Residual Connection)
残差模块基于恒等映射的思想:
它让梯度更容易向前传播,允许训练更深的网络(ResNet)。残差可以是逐元素相加(当通道数不匹配时使用 1x1 卷积投影)。
6.17.2 瓶颈结构(Bottleneck)
ResNet 的瓶颈块先用 1x1 降维,再用 3x3 计算特征,最后用 1x1 恢复通道数,从而降低计算量。
6.17.3 DenseNet 的密集连接
DenseNet 将前面所有层的输出拼接作为后续层的输入,鼓励特征复用并减少参数量。
6.17.4 注意力机制(SE、CBAM 等)
注意力模块常按通道或空间加权特征,以增强重要通道或位置的响应(如 SE-block 的通道注意力)。
6.18 经典与现代视觉架构速览
- LeNet:较浅网络,适合手写数字识别;
- AlexNet:引入 ReLU、Dropout、大型数据增强,是现代 CNN 的里程碑;
- VGG:使用多层小核(3x3)堆叠,结构简单但参数多;
- ResNet:残差连接使超深网络易于训练;
- DenseNet:密集连接,特征复用;
- MobileNet/ShuffleNet:轻量化网络,使用深度可分离卷积与通道混洗;
- EfficientNet:通过复合缩放法在宽度、深度与分辨率间寻优;
- Vision Transformer(ViT):基于 Transformer 的图像建模,打破了卷积固有的局部归纳偏置。
理解架构演进的关键在于:如何在表达能力、计算效率与泛化之间做权衡。
6.19 迁移学习与微调策略
迁移学习常见流程:
- 选用预训练模型(ImageNet 或更大数据集);
- 替换最后一层以匹配目标任务类别;
- 可选择冻结前若干层并只训练最后几层;
- 逐步解冻并使用较小的学习率微调整个网络;
- 记录验证集性能并使用早停。
实践建议:
- 小数据集优先冻结大部分卷积层;
- 使用较小的初始化学习率(如 1e-4);
- 若使用 BatchNorm,注意训练/推理模式与小 batch 的统计不稳定问题。
6.20 数据增强与正则化技巧(视觉任务专用)
进阶增强方法:
- Mixup:把两张图片和其标签按比例混合;
- CutMix:在一张图上切换一块区域并替换为另一张图的相应区域,标签按像素比例混合;
- AutoAugment / RandAugment:自动或随机搜索增强策略;
- Mosaic:把多张图片拼接成一个训练样本,常见于目标检测(YOLOv4)。
增强实践要点:
- 在训练时使用增强,验证时不要使用(或仅用中心裁剪/缩放);
- 一些增强对小目标检测效果差,需按任务调整;
- Mixup 与 CutMix 在分类任务中通常能提升泛化,但会降低可解释性。
6.21 训练与调参实战清单(视觉)
- 数据准备:保证分割与检测任务的标注无误;
- 小样本过拟合检查:能否在较小子集上过拟合?若不能,说明实现有问题;
- 学习率策略:先用 LR-finder 找到合适初始 lr,再用 warmup + cosine 或 step decay;
- Batch size 与学习率线性缩放:当增大 batch 时,适当增大学习率并延长训练;
- 增加验证集频率以捕捉早期过拟合;
- 记录训练/验证 loss、top-k accuracy、mAP(检测)、IoU(分割)。
6.22 评估指标(视觉任务)
分类:Top-1 / Top-5 accuracy
目标检测:mAP@IoU(常用 0.5 或 0.5:0.95)
语义分割:mIoU(mean Intersection over Union)
实例分割:AP (Average Precision) with mask IoU
注意:选择符合下游业务的指标而非盲目追求单一数字。
6.23 可视化与可解释性(Grad-CAM 等)
Grad-CAM 通过卷积特征图与上游梯度的加权和可视化网络关注区域,常用于定位模型判断依据并排查模型错误。
实现要点:
- 选用最后一层或浅层卷积特征图做 Grad-CAM;
- 用 ReLU 去掉负权重以获得更清晰的热力图;
- 把热力图叠加到原图上便于观察。
6.24 实战代码:NumPy 实现的 im2col 卷积(前向与反向)
下面给出简化的单通道 im2col 前向与反向实现(用于教学与梯度检验):
import numpy as np
def im2col(X, k_h, k_w, stride=1, pad=0): N, H, W = X.shape H_p = H + 2*pad W_p = W + 2*pad Xp = np.pad(X, ((0,0),(pad,pad),(pad,pad)), mode='constant') out_h = (H_p - k_h)//stride + 1 out_w = (W_p - k_w)//stride + 1 cols = np.zeros((N, k_h*k_w, out_h*out_w)) col_idx = 0 for i in range(0, H_p - k_h + 1, stride): for j in range(0, W_p - k_w + 1, stride): patch = Xp[:, i:i+k_h, j:j+k_w].reshape(N, -1) cols[:, :, col_idx] = patch col_idx += 1 return cols # shape (N, k_h*k_w, out_h*out_w)
def col2im(cols, X_shape, k_h, k_w, stride=1, pad=0): N, H, W = X_shape H_p = H + 2*pad W_p = W + 2*pad Xp = np.zeros((N, H_p, W_p)) out_h = (H_p - k_h)//stride + 1 out_w = (W_p - k_w)//stride + 1 col_idx = 0 for i in range(0, H_p - k_h + 1, stride): for j in range(0, W_p - k_w + 1, stride): patch = cols[:, :, col_idx].reshape(N, k_h, k_w) Xp[:, i:i+k_h, j:j+k_w] += patch col_idx += 1 if pad == 0: return Xp return Xp[:, pad:-pad, pad:-pad]
def conv_forward_simple(X, K, stride=1, pad=0): # X: (N, H, W), K: (k_h, k_w) N, H, W = X.shape k_h, k_w = K.shape cols = im2col(X, k_h, k_w, stride, pad) Kcol = K.reshape(-1) out = np.tensordot(cols, Kcol, axes=([1],[0])) # (N, out_h*out_w) return out.reshape(N, (H + 2*pad - k_h)//stride + 1, (W + 2*pad - k_w)//stride + 1), cols
def conv_backward_simple(dout, cols, X_shape, k_h, k_w, stride=1, pad=0): # dout: (N, out_h, out_w) N, out_h, out_w = dout.shape dout_flat = dout.reshape(N, -1) # gradient wrt kernel dKcol = np.tensordot(dout_flat, cols, axes=([0,1],[0,2])) dK = dKcol.reshape(k_h, k_w) # gradient wrt input via col2im # compute contribution of each col multiplied by kernel entries # simplified here for teaching; production code should optimize return dK注:此代码为教学示例,生产环境请使用框架高效接口。
6.25 PyTorch 训练脚本骨架(视觉任务)
下面给出训练脚本的伪代码骨架,覆盖数据、模型、优化器、LR 调度、checkpoint 与日志:
def train_loop(model, train_loader, val_loader, cfg): optimizer = torch.optim.SGD(model.parameters(), lr=cfg.lr, momentum=0.9, weight_decay=cfg.wd) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=cfg.epochs) best_val = 1e9 for epoch in range(cfg.epochs): model.train() for batch in train_loader: images, targets = batch preds = model(images) loss = criterion(preds, targets) optimizer.zero_grad() loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=5.0) optimizer.step() scheduler.step() val_loss = validate(model, val_loader) if val_loss < best_val: best_val = val_loss save_checkpoint(model, optimizer, epoch, best_val)6.26 常见问题与排查(视觉训练)
- Loss 为 NaN:检查输入是否含 Inf/NaN,检查学习率是否过大,检查数值稳定操作(log/softmax)。
- 验证集突然变差:可能是数据泄漏、训练-验证分布差异或 augmentation 在验证时不一致。
- 训练很慢或显存占满:检查 batch size、模型尺寸、是否使用混合精度(AMP)。
- 检测到棋盘伪影:避免使用不当的反卷积,或者使用上采样+卷积替代反卷积。
6.27 章节级项目(实战)
项目 A:CIFAR-10 基线与增强实验
- 任务:在 CIFAR-10 上训练 ResNet-18 基线,记录 top-1 accuracy 与训练/验证 loss 曲线。
- 要点:实现数据增强、训练脚本、lr schedule、checkpoint 保存、实验日志。
- 拓展:加入 Mixup、CutMix 或 AutoAugment,比较提升效果并写实验报告。
项目 B:基于预训练模型的迁移学习
- 任务:用 ImageNet 预训练的 ResNet 在一个小型自定义数据集上做微调,尝试冻结不同层数并比较效果。
- 要点:处理小 batch 对 BatchNorm 的影响,选择合适的微调学习率与 epoch。
6.28 本章小结(扩展)
本章深入了卷积运算的数学与实现细节,介绍了多种卷积变体与现代视觉网络的设计思路,并给出了训练、调参与排查的实践清单。掌握这些内容能让你在图像任务中更有效地设计模型与解决工程问题。
6.29 参考资料与延伸阅读
- “Deep Learning” — Goodfellow, Bengio, Courville(卷积与 Vision 章节)
- “ImageNet Classification with Deep Convolutional Neural Networks” — Alex Krizhevsky et al.
- “Deep Residual Learning for Image Recognition” — He et al.
- MobileNet / EfficientNet / ResNeXt / DenseNet 相关论文与实现
如果這篇文章對你有幫助,歡迎分享給更多人!
部分資訊可能已經過時





















