共计 2725 个字符,预计需要花费 7 分钟才能阅读完成。
背景介绍
卷积神经网络(CNN)是计算机视觉领域的基石,而 VGGNet 和 GoogLeNet 作为其中的经典模型,不仅具有里程碑意义,更是理解现代 CNN 架构的绝佳起点。VGGNet 以其简洁的深度堆叠结构闻名,GoogLeNet 则通过创新的 Inception 模块展现了网络设计的另一种思路。对于初学者而言,掌握这两种模型能快速建立对 CNN 的直观认识,并为后续学习更复杂网络(如 ResNet)打下基础。

架构对比
VGGNet 的深度卷积网络设计
VGGNet 的核心思想是使用连续的 3×3 小卷积核替代大尺寸卷积核(如 5×5 或 7×7),这种设计有两个显著优势:
- 在相同感受野下,多个小卷积核比单个大卷积核具有更少的参数量。例如,三个 3×3 卷积堆叠(不含非线性层)的参数量为 3×(3×3×C×C)=27C²,而一个 7×7 卷积的参数量为 49C²。
- 通过增加网络深度(层数),可以引入更多非线性激活函数(ReLU),增强模型的表达能力。
VGGNet 常见的有 VGG16 和 VGG19 两种配置,数字代表带有可训练参数的层数(不含池化层)。所有隐藏层都使用 ReLU 激活函数,并在最后接三个全连接层。
GoogLeNet 的 Inception 模块创新
GoogLeNet 的最大突破是提出了 Inception 模块,其核心设计理念是:
- 在同一层上并行应用不同尺度的卷积运算(1×1、3×3、5×5)和池化操作
- 使用 1×1 卷积(” 网络中的网络 ”)进行降维,控制计算量
- 通过多尺度特征融合增强模型对不同大小目标的识别能力
这种结构显著减少了参数量(GoogLeNet 约 500 万参数,VGG16 约 1.38 亿),同时保持了较高的识别准确率。
参数量与计算复杂度对比
| 模型 | 参数量 | FLOPs(百万) | Top- 5 错误率(ImageNet) |
|---|---|---|---|
| VGG16 | 138M | 15,500 | 7.4% |
| GoogLeNet | 5M | 1,500 | 6.7% |
代码实现
VGG16 实现(PyTorch)
import torch.nn as nn
class VGG16(nn.Module):
def __init__(self, num_classes=10):
super(VGG16, self).__init__()
# 特征提取部分
self.features = nn.Sequential(
# Block 1: 2 个 Conv+ReLU -> MaxPool
nn.Conv2d(3, 64, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
# Block 2-5: 类似结构,通道数逐渐增加
# ...(完整实现应包含所有 5 个 block))
# 分类器部分
self.classifier = nn.Sequential(nn.Linear(512*7*7, 4096), # 假设输入为 224x224
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1) # 展平
x = self.classifier(x)
return x
GoogLeNet 实现关键部分
class Inception(nn.Module):
def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch5x5red, ch5x5, pool_proj):
super(Inception, self).__init__()
# 1x1 卷积分支
self.branch1 = nn.Sequential(nn.Conv2d(in_channels, ch1x1, kernel_size=1),
nn.ReLU(inplace=True)
)
# 1x1->3x3 分支
self.branch2 = nn.Sequential(nn.Conv2d(in_channels, ch3x3red, kernel_size=1),
nn.ReLU(inplace=True),
nn.Conv2d(ch3x3red, ch3x3, kernel_size=3, padding=1),
nn.ReLU(inplace=True)
)
# 其他分支类似...
def forward(self, x):
# 合并各分支输出
return torch.cat([self.branch1(x),
self.branch2(x),
# ... 其他分支
], 1)
训练实践
CIFAR-10 训练配置
- 数据预处理 :
- 归一化:均值 [0.4914, 0.4822, 0.4465],标准差 [0.2470, 0.2435, 0.2616]
-
数据增强:随机水平翻转、随机裁剪(padding=4)
-
训练参数 :
- Batch size:128
- 初始学习率:0.1(VGG16)、0.01(GoogLeNet)
- 优化器:SGD with momentum=0.9
- 学习率调整:每 30 个 epoch 乘以 0.1
-
总 epochs:100
-
Loss 曲线分析 :
- VGG16 初期收敛较快,但容易在后期出现过拟合
- GoogLeNet 训练更稳定,但需要更精细的学习率调整
性能对比
在 NVIDIA RTX 2080Ti 上的测试结果:
- 推理速度 (batch=32,224×224 输入):
- VGG16:120 FPS
-
GoogLeNet:210 FPS
-
显存占用 :
- VGG16:约 1.2GB
- GoogLeNet:约 0.6GB
避坑指南
- 梯度消失问题 :
- 对 VGGNet:使用 BatchNorm 层(原论文未使用)
-
对 GoogLeNet:确保辅助分类器的梯度正确回传
-
过拟合解决方案 :
- 增加 Dropout 率(VGG16 建议 0.5)
- 使用更强的数据增强
-
添加 L2 正则化
-
部署优化建议 :
- 将模型转换为 ONNX 格式
- 使用 TensorRT 加速
- 对 GoogLeNet,可以移除辅助分类器
总结与思考
VGGNet 凭借其规整的结构,非常适合作为教学案例和迁移学习的基础模型。而 GoogLeNet 的高效设计,使其在资源受限的场景下更具优势。对于后续学习建议:
- 理解残差连接(ResNet)如何解决深度网络的梯度问题
- 研究 MobileNet 等轻量级模型的优化技巧
- 实践模型压缩技术(如量化、剪枝)在经典网络上的应用
通过这两个经典模型的学习,读者不仅能掌握 CNN 的基本原理,还能培养对网络设计的直觉,为后续研究更复杂的视觉任务奠定坚实基础。
