卷积神经网络(CNN)是计算机视觉的基石。本课从卷积的数学定义出发,理解卷积核、步长、填充等核心概念,并用PyTorch验证。
(f * g)(t) = ∫ f(τ)g(t-τ)dτ
注意:一个函数翻转后滑动相乘积分
Y[i,j] = Σₘ Σₙ X[i+m, j+n] · K[m,n]
深度学习中实际用的是互相关(cross-correlation),不翻转核
| 参数 | 含义 | 影响 |
|---|---|---|
| kernel_size | 卷积核大小 | 感受野 |
| stride | 步长 | 输出尺寸 |
| padding | 填充 | 边界处理 |
| dilation | 膨胀 | 扩大感受野 |
输出尺寸 = ⌊(输入尺寸 + 2×padding - dilation×(kernel-1) - 1) / stride⌋ + 1
import torch
import torch.nn as nn
import torch.nn.functional as F
# 卷积操作详解
print("=== 卷积参数计算 ===")
# 输入1×5×5,3×3卷积核
x = torch.arange(25, dtype=torch.float32).reshape(1, 1, 5, 5)
print(f"输入张量: shape={x.shape}")
print(x.reshape(5, 5))
# 基本卷积
conv = nn.Conv2d(1, 1, kernel_size=3, bias=False)
with torch.no_grad():
conv.weight[:] = torch.ones(1, 1, 3, 3) / 9 # 均值滤波器
out = conv(x)
print(f"\n3×3卷积(无padding): 输出shape={out.shape}")
print(out.reshape(3, 3).detach())
# 带padding
conv_pad = nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False)
with torch.no_grad():
conv_pad.weight[:] = torch.ones(1, 1, 3, 3) / 9
out_pad = conv_pad(x)
print(f"\n3×3卷积(padding=1): 输出shape={out_pad.shape}")
# 带stride
conv_stride = nn.Conv2d(1, 1, kernel_size=3, stride=2, bias=False)
with torch.no_grad():
conv_stride.weight[:] = torch.ones(1, 1, 3, 3) / 9
out_stride = conv_stride(x)
print(f"3×3卷积(stride=2): 输出shape={out_stride.shape}")
# 多通道卷积
x_rgb = torch.randn(1, 3, 32, 32)
conv_multi = nn.Conv2d(3, 16, kernel_size=3, padding=1)
out_multi = conv_multi(x_rgb)
print(f"\n3通道→16通道 3×3卷积: {x_rgb.shape} → {out_multi.shape}")
print(f"参数量: 3×16×3×3 + 16 = {3*16*3*3 + 16}")
# 输出尺寸公式验证
print("\n=== 输出尺寸公式验证 ===")
formulas = [
("7×7, k=3, s=1, p=0", 7, 3, 1, 0),
("7×7, k=3, s=1, p=1", 7, 3, 1, 1),
("7×7, k=3, s=2, p=0", 7, 3, 2, 0),
("7×7, k=3, s=2, p=1", 7, 3, 2, 1),
("32×32, k=5, s=1, p=2", 32, 5, 1, 2),
]
for desc, inp, k, s, p in formulas:
out_size = (inp + 2*p - k) // s + 1
actual = nn.Conv2d(1, 1, k, s, p)(torch.randn(1, 1, inp, inp)).shape[-1]
print(f"{desc}: 公式={out_size}, 实际={actual}, {'✓' if out_size==actual else '✗'}")
| 特性 | 全连接 | 卷积 |
|---|---|---|
| 参数量 | 输入×输出 | 核大小×通道数 |
| 连接模式 | 全连接 | 局部连接 |
| 权重共享 | 无 | 有(同一核在所有位置) |
| 平移不变性 | 无 | 有 |
| 适合数据 | 结构化数据 | 图像/时序 |
一个3×3卷积核只有9个参数,但能在整张图上滑动检测同一模式——这就是权重共享的威力。
单层3×3卷积:感受野 = 3
两层3×3卷积:感受野 = 5
三层3×3卷积:感受野 = 7
通用公式:RF_l = RF_{l-1} + (k_l - 1) × ∏_{i=1}^{l-1} s_i
深层网络通过逐层累积,最终每个输出单元可以"看到"很大区域
标准卷积:输入C_in → 输出C_out,参数 = k²×C_in×C_out
分组卷积:将通道分成g组,每组独立卷积,参数减少到 1/g
深度可分离卷积 = 深度卷积(C_in组) + 逐点卷积(1×1)
参数比 = 1/C_out + 1/k² (MobileNet的核心)
💡 推荐资源:
实现Sobel边缘检测核和锐化核,对图像应用并观察效果。
实现dilation=2的卷积,对比感受野和参数量。
实现MobileNet的深度可分离卷积,计算参数量节省比例。
| 场景 | kernel_size | stride | padding |
|---|---|---|---|
| 特征提取(不降采样) | 3 | 1 | 1 |
| 降采样 | 3 | 2 | 1 |
| 大感受野 | 5或7 | 1 | 2或3 |
| 1×1卷积(降维) | 1 | 1 | 0 |
| 全局信息 | 等于输入尺寸 | 1 | 0 |
在构建CNN时,追踪每一层的特征图尺寸至关重要。常见错误:
理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:
建立正确的直觉比记住公式更重要:
1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)
2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的
3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构
4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)
本课作为CNN阶段的核心内容,与前后课程紧密关联:
| 关联课程 | 关联点 | 协同效应 |
|---|---|---|
| 前序课程 | 提供了本课的基础知识 | 循序渐进的理解 |
| 后续课程 | 本课内容是后续的基础 | 逐步构建能力 |
| 平行课程 | 同一阶段的互补知识 | 多角度深入理解 |
| 实战项目 | 综合运用所有知识 | 理论与实践结合 |
💡 准备面试时,确保能回答以下问题:
掌握本课内容后,可以通过以下方式继续深入:
将本课涉及的关键公式整理如下,方便回顾和记忆。理解每个公式背后的直觉比死记硬背更重要——试着用自然语言解释每个公式在做什么。
| 概念A | 概念B | 关键区别 |
|---|---|---|
| 参数 | 超参数 | 参数通过训练学习,超参数需要手动设定 |
| 训练误差 | 泛化误差 | 训练误差衡量拟合程度,泛化误差衡量预测能力 |
| 偏差 | 方差 | 偏差是系统性误差,方差是随机波动 |
| L1正则 | L2正则 | L1产生稀疏解,L2产生平滑解 |
| BatchNorm | LayerNorm | BN沿batch维度,LN沿特征维度 |
以下是本课核心概念的标准PyTorch实现模板,可以直接用于实际项目:
💡 调试建议:当结果不符合预期时,先检查数据,再检查损失函数,最后检查模型结构。90%的问题出在前两个环节。
卷积是CNN的灵魂——你已经理解了计算机视觉的基础操作!