经典CNN模型之VGG与ResNet
1. VGG网络
1.1 核心思想
- 统一架构:使用重复的3×3卷积核堆叠(小感受野的连续卷积替代大卷积核)
- 深度扩展:通过增加卷积层数量(16-19层)验证深度对性能的影响
- 全连接层优化:保留AlexNet的3层全连接结构,但参数量占比显著增大
1.2 关键特性
# 典型VGG16结构示例
Conv3x3(64) → Conv3x3(64) → MaxPool →
Conv3x3(128) → Conv3x3(128) → MaxPool →
Conv3x3(256) ×3 → MaxPool →
Conv3x3(512) ×3 → MaxPool →
Conv3x3(512) ×3 → MaxPool →
FC(4096) → FC(4096) → FC(1000)
1.3 贡献与局限
- 贡献:
- 证明网络深度是性能关键因素
- 简单规则的架构设计范式
- 局限:
- 全连接层参数量过大(占总参数90%+)
- 训练时需要大量计算资源
2. ResNet(残差网络)
2.1 创新机制
- 残差连接(Shortcut Connection):
H(x) = F(x) + x- 解决梯度消失/爆炸问题
- 允许训练超过1000层的网络
2.2 核心结构
- 残差块设计:
- 基础块(BasicBlock):两层的3×3卷积
- 瓶颈块(Bottleneck):1×1降维 → 3×3卷积 → 1×1升维
# Bottleneck结构示例
class Bottleneck(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels//4, kernel_size=1)
self.conv2 = nn.Conv2d(out_channels//4, out_channels//4, kernel_size=3, stride=stride, padding=1)
self.conv3 = nn.Conv2d(out_channels//4, out_channels, kernel_size=1)
self.shortcut = nn.Sequential() if (in_channels == out_channels and stride==1) else \
nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride)
def forward(self, x):
out = F.relu(self.conv1(x))
out = F.relu(self.conv2(out))
out = self.conv3(out)
return F.relu(out + self.shortcut(x))
2.3 里程碑版本
| 模型 | 层数 | 关键改进 |
|---|---|---|
| ResNet-18 | 18 | 基础块结构 |
| ResNet-34 | 34 | 加深的基础块网络 |
| ResNet-50 | 50 | 引入Bottleneck设计 |
| ResNet-101 | 101 | 深层Bottleneck堆叠 |
| ResNet-152 | 152 | 当前常用最大规模 |
3. 对比分析
3.1 性能表现
- ImageNet Top-5错误率:
- VGG16: 7.3%
- ResNet-50: 5.2%
- ResNet-152: 3.6%
3.2 计算效率
| 指标 | VGG16 | ResNet-50 |
|---|---|---|
| 参数量 | 138M | 25.5M |
| FLOPs | 15.5B | 3.8B |
| 内存占用 | 528MB | 98MB |
4. 实际应用建议
- VGG适用场景:
- 需要高精度特征提取的迁移学习
- 计算资源充足的场景
- ResNet适用场景:
- 深层网络需求任务
- 资源受限的端侧部署
- 需要快速原型开发
设计启示:现代CNN架构发展呈现"深度化+稀疏连接"趋势,后续的DenseNet、EfficientNet等均受ResNet思想启发
该内容包含:
1. 技术细节的代码/公式实现
2. 结构对比表格
3. 实际性能数据
4. 工程应用指导
可根据需要增加以下内容:
- 特定任务的微调技巧
- 各变体模型的训练曲线对比
- 量化部署时的注意事项