深度学习 5 — 卷积网络 (3/3)
:::tip Kaggle 笔记本 本章的完整可执行代码在 Kaggle 上:打开 →
法语和英语版本可在首页查看。 :::
如今几乎没人在真实数据上从零训练 CNN:我们从预训练模型开始。最后一章涵盖迁移学习,然后开放到使用 YOLO 的目标检测。
为什么要学这一章?
您将看到:
- 模型动物园:ResNet、VGG、MobileNet、EfficientNet;
- 作为动物园现代演化的基础模型;
- 两种迁移学习策略:特征提取和微调;
- 从分类到目标检测的过渡;
- YOLO 的思想和使用。
模型动物园
我们不是从头构建架构,而是依赖预训练网络的模型动物园。在视觉领域,标准是 torchvision.models:
| 系列 | 变体 | 特征 |
|---|---|---|
| ResNet | 18, 50, 101, 152 | 残差连接,主力军 |
| VGG | 11, 16, 19 | 非常深的堆叠,参数多 |
| DenseNet | 121, 161, 201 | 层之间的密集连接 |
| MobileNet | V2, V3 | 为移动 / 边缘优化 |
| EfficientNet | B0 至 B7 | 优化的效率 / 准确率比 |
每个都在 ImageNet(约 120 万张图像,1000 类)上训练——巨大的计算成本,我们免费受益。
基础模型
ImageNet 动物园是更广泛思想的祖先:基础模型。在大量数据上训练(通常通过自监督),它们用作数十种任务的起点,特定任务数据非常少。
- 视觉:CLIP、DINO、SAM
- 文本:GPT、Llama、Mistral
- 多模态:当前的所有热潮
迁移学习:核心思想
CNN 的早期层学习一般表示(边缘、纹理、简单模式),后期层学习特定任务的决策。
后果:如果我们有在 ImageNet 上训练的模型,想要分类医疗 X 光或植物,我们可以重用早期层,仅重新学习最后的层。
两种策略
1. 特征提取(冻结)
我们冻结整个预训练模型,只替换最后一层,仅训练那一层。
from torchvision import models
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
# 冻结所有
for param in model.parameters():
param.requires_grad = False
# 替换头部(1000 ImageNet 类 → 新的 n_classes)
model.fc = nn.Linear(model.fc.in_features, n_classes)
# 仅 model.fc 参数可训练
optimizer = torch.optim.Adam(model.fc.parameters(), lr=1e-3)
优点: 非常快,过拟合风险低,即使数据很少也有效。
2. 微调
我们解冻所有(或仅后期层)并以比通常小的 lr 继续训练,以避免破坏学到的良好表示。
for param in model.parameters():
param.requires_grad = True
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # 小 lr!
优点: 比特征提取性能更好。缺点: 成本更高,风险更大(数据少时过拟合)。
何时使用哪种策略?
| 情况 | 策略 |
|---|---|
| 数据非常少(< 1000) | 特征提取(完全冻结) |
| 大量数据(> 10k) | 完全微调 |
| 与 ImageNet 非常不同的领域 | 微调,先解冻后期层 |
| 嵌入式生产 | 微调 MobileNet 或 EfficientNet |
目标检测
分类 vs 检测
分类回答"这张图像中有什么?",用单一标签。
检测回答"哪些对象存在,在哪里,是什么类型?",每张图像可能有多个输出。
边界框(bounding box)由其位置 和大小 定义。网络必须为每个对象预测:类别、框和置信度分数。
为什么单独的分类器不够
分类 CNN 通过 MaxPool 逐步压缩图像,丢失精细的空间信息,并以单一全局输出结束。擅长识别,不擅长定位。
YOLO 的思想
YOLO(You Only Look Once,Redmon et al., 2016)提出了一个简单的革命:
在网络的单个前向传递中完成所有检测。
YOLO 不是裁剪和重新分类,而是:
- 一次性处理整个图像;
- 隐式将其切成网格(例如 13×13);
- 对网格的每个单元,直接预测可能的类别、几个候选框及其置信度分数。
单个前向传递产生所有检测。结果:YOLO 可以实时运行(现代 GPU 上 30+ FPS)。
YOLO 格式和 Ultralytics 训练
YOLO 格式的数据集:
dataset_yolo/
├── images/
│ ├── train/
│ ├── val/
├── labels/
│ ├── train/
│ ├── val/
└── data.yaml
每张图像在 labels/ 中有一个相关的 .txt 文件(相同的基础名称),格式为:
class_id x_centre y_centre width height
坐标在 0 和 1 之间归一化。
使用 Ultralytics 训练
from ultralytics import YOLO
model = YOLO("yolov8n.pt") # 'n' = nano
model.train(
data="data.yaml",
imgsz=640,
epochs=20,
batch=16,
)
主干在 ImageNet 上预训练——免费的迁移学习。
检测指标
| 指标 | 描述 |
|---|---|
| mAP50 | IoU 阈值 0.5 时的平均精度 |
| mAP50-95 | IoU 阈值 0.5 至 0.95 的平均(更严格) |
| 精确率 / 召回率 | 每类 |
IoU(交并比)测量预测框和真实框之间的重叠。如果 IoU ≥ 阈值,则检测被认为是正确的。
总结
您现在拥有解决大多数现代计算机视觉问题的基础:
- 理解 CNN 如何学习空间表示;
- 根据数据量选择特征提取或微调;
- 区分分类和检测;
- 拥有"从预训练模型开始"的反射,而不是重新发明。
走得更远:分割(Mask R-CNN、U-Net)、生成(Stable Diffusion)、视觉语言(CLIP、BLIP)、视觉 transformer(ViT、DETR)。