3、卷积神经网络(CNN)选型:经典CNN架构的适用场景与选型对比
说到CNN选型,很多同学一上来就问我:“老师,到底哪个网络最好?”
说实话,这个问题没有标准答案。我做了这么多年模型选型,最深的体会是——没有最好的网络,只有最合适的网络。你想想看,让LeNet去跑ImageNet,那不是让小学生做高考题吗?
3.1 经典CNN架构速览
我们先快速过一遍这几个经典架构的核心特点。我个人习惯把它们分成三代:
| 架构 | 诞生年份 | 核心创新 | 参数量 | 典型输入尺寸 |
|---|---|---|---|---|
| LeNet-5 | 1998 | 卷积+池化+全连接的基础范式 | ~60K | 32×32 |
| AlexNet | 2012 | ReLU、Dropout、GPU并行 | ~60M | 227×227 |
| VGG16/19 | 2014 | 小卷积核堆叠、结构规整 | ~138M | 224×224 |
| ResNet50/101 | 2015 | 残差连接(Skip Connection) | ~25M | 224×224 |
| EfficientNet-B0~B7 | 2019 | 复合缩放(深度/宽度/分辨率) | 5.3M~66M | 224~600 |
关键洞察:从LeNet到EfficientNet,参数量增长了1000倍,但精度提升并不是线性的。很多时候,小模型+好数据 > 大模型+烂数据。
3.2 各架构的适用场景
LeNet-5:老当益壮的入门选手
LeNet当年是为手写数字识别设计的。现在用它做复杂图像分类肯定不行,但有两个场景我经常推荐:
- 教学演示:结构简单,一眼能看懂卷积、池化、全连接是怎么配合的
- 极低资源场景:比如MCU上的简单字符识别,60K参数随便跑
我记得有一次给嵌入式团队做方案,他们只有256KB的Flash空间。ResNet想都别想,最后就是用LeNet改了一版,效果出奇的好。
AlexNet:历史意义大于实用价值
说实话,现在很少直接拿AlexNet做项目了。但它有两个贡献至今受用:
- ReLU激活函数:解决了梯度消失问题,现在几乎所有CNN都在用
- Dropout:简单粗暴但有效的正则化手段
避坑指南:我曾经在项目里直接复用AlexNet的原始超参数(学习率0.01、batch size 128),结果训练直接炸了。后来才发现,AlexNet用了两块GTX 580做数据并行,batch size是翻倍的。现在的显卡显存更大,但学习率要跟着batch size调,这个坑我替你们踩过了。
VGG:规整到极致的“砖头”
VGG的结构非常规整——全部用3×3卷积和2×2池化。这种设计带来两个好处:
- 容易移植:结构固定,改网络就像搭积木
- 特征提取能力强:小卷积核堆叠,感受野大,非线性强
但VGG的参数量太大了(138M),我一般只在两种情况下用它:
- 做特征提取的backbone:比如风格迁移、目标检测里的基础网络
- 对比实验的baseline:VGG是很多的标配,用它做对比有说服力
注意:VGG的全连接层占了绝大部分参数。如果你只是想用卷积层做特征提取,可以砍掉全连接层,换成全局平均池化,参数量能降到原来的1/10。
ResNet:残差连接,深度的救星
ResNet是我用得最多的架构。它的核心思想很简单:让网络学习残差F(x)=H(x)-x,而不是直接学习H(x)。
为什么会这样?因为直接学习恒等映射太难了。你想想看,让一个深层网络去拟合y=x,梯度很容易消失。但让网络去拟合y=0,那就简单多了——把权重全设成0就行。
ResNet的适用场景非常广:
- 图像分类:ResNet50是工业界的标配
- 目标检测:Faster R-CNN、YOLO的backbone首选
- 语义分割:DeepLab、PSPNet都基于ResNet
个人经验:我一般默认用ResNet50。如果资源紧张就降到ResNet18,如果追求极致精度就上ResNet152。但说实话,ResNet101和ResNet152的差距已经很小了,很多时候数据质量比网络深度更重要。
EfficientNet:效率与精度的平衡大师
EfficientNet是Google在2019年提出的,核心创新是复合缩放——同时调整网络的深度、宽度和输入分辨率。
以前我们调网络,要么加深(ResNet),要么加宽(Inception),要么提分辨率。但EfficientNet告诉你:这三个维度要一起调,而且有最优比例。
EfficientNet的适用场景:
- 移动端部署:EfficientNet-B0只有5.3M参数,精度比ResNet50还高
- 高精度需求:EfficientNet-B7在ImageNet上达到84.4% top-1精度,当时是SOTA
- 资源受限场景:B0到B7覆盖了从5M到66M的参数范围,按需选择
避坑指南:我曾经在项目里直接用了EfficientNet-B7,结果训练速度慢得离谱。后来才发现,B7的输入分辨率是600×600,比B0的224×224大了近8倍。如果你用B7,记得先确认你的GPU显存够不够。我建议从B3或B4开始试,性价比最高。
3.3 选型对比:一张图说清楚
下面这张图是我自己总结的选型决策流程,每次做项目前我都会过一遍:
3.4 实战选型清单
最后,我整理了一份选型清单。每次做项目前,我都会对照着问自己几个问题:
- 你的硬件是什么?
- MCU/FPGA → LeNet或MobileNet
- 手机/平板 → EfficientNet-B0~B3
- 服务器GPU → ResNet50/101或EfficientNet-B4~B7
- 你的数据量有多大?
- <1万张 → 用预训练模型做迁移学习,别从头训
- 1万~10万张 → ResNet50或EfficientNet-B3
- >10万张 → 可以尝试EfficientNet-B7或自己设计网络
- 你的延迟要求是多少?
- 实时(<30ms) → 轻量网络,考虑量化
- 准实时(30~100ms) → ResNet50或EfficientNet-B3
- 离线(>100ms) → 随便选,精度优先
最后提醒一句:别在选型上花太多时间。我见过太多同学花两周选网络,结果训练一周发现数据有问题。我的建议是——先用ResNet50跑通流程,再根据瓶颈优化。选型是迭代出来的,不是想出来的。