当前位置: 首页 > news >正文

经典 CNN 网络 VGG

一、VGG 网络诞生背景

VGGNet 由牛津大学视觉几何组 VGG 联合 Google DeepMind 提出,亮相于 2014 年 ImageNet 图像分类竞赛 ILSVRC-2014,最终拿下亚军,当年冠军为 GoogLeNet。

日常大家口中的 VGG,默认指VGG-16,包含 13 层卷积层 + 3 层全连接层,总权重层 16 层;另有加深版本 VGG-19(19 层权重)。 对比初代深度 CNN AlexNet,VGG 核心优势:

  1. 网络深度更深,特征提取能力更强;
  2. 结构规整、模块化,易复现、易迁移;
  3. 泛化性能优秀,后续检测、分割任务大量用作骨干网络; VGG-16 总参数量约 1.38 亿,相比 AlexNet 参数量更大,对硬件算力、存储有更高要求。

二、VGG 全套网络配置(6 种结构 A/A-LRN/B/C/D/E)

论文一共给出 6 种不同深度的 VGG 结构,区别仅在于卷积层堆叠数量:

表格

结构权重层数核心差异总参数量(百万)
A11 层最少卷积,无重复堆叠133
A-LRN11 层在 A 基础上增加 LRN 局部归一化层133
B13 层增加两组 3×3 卷积堆叠133
C16 层在 B 基础上插入 1×1 卷积134
D(VGG16)16 层全部使用 3×3 卷积堆叠,工业最常用138
E(VGG19)19 层进一步加深卷积堆叠层数144

实验证明两点关键结论:

  1. AlexNet 中的 LRN 局部响应归一化层提升极小,后续主流 VGG16/19 全部舍弃;
  2. 单纯堆叠 3×3 卷积比插入 1×1 卷积效果更好,因此 VGG16 (D) 成为标准版本。

三、VGG 核心结构:VGG Block 模块化设计

VGG 最标志性设计就是VGG 块(vgg-block),整套网络由重复的卷积块 + 池化层串联而成,结构高度统一: 单个 Block 标准流程:多层3×3卷积(ReLU激活) → 2×2最大池化MaxPool

卷积统一超参(所有卷积层通用)

  • 卷积核:3×3
  • 步幅 stride=1
  • 填充 padding=1 作用:卷积前后特征图宽高尺寸不变,方便多层堆叠。

池化统一超参(所有池化层通用)

  • 池化核:2×2
  • 步幅 stride=2 作用:每经过一个 Block,特征图宽、高减半,尺寸规整递减:224 → 112 → 56 → 28 → 14 → 7

四、VGG16 逐层完整维度拆解(输入 224×224×3 RGB 图)

VGG16 一共 5 个 VGG 卷积块,5 次下采样池化,末尾接三层全连接 + Softmax 输出。

Block1(2 层 Conv)

  1. 输入:224×224×3 → Conv3-64 → 224×224×64 + ReLU
  2. Conv3-64 → 224×224×64 + ReLU
  3. MaxPool2×2/2 → 输出 112×112×64

Block2(2 层 Conv)

  1. 输入:112×112×64 → Conv3-128 → 112×112×128 + ReLU
  2. Conv3-128 → 112×112×128 + ReLU
  3. MaxPool2×2/2 → 输出 56×56×128

Block3(3 层 Conv)

  1. 输入:56×56×128 → Conv3-256 ×3 → 56×56×256
  2. MaxPool2×2/2 → 输出 28×28×256

Block4(3 层 Conv)

  1. 输入:28×28×256 → Conv3-512 ×3 → 28×28×512
  2. MaxPool2×2/2 → 输出 14×14×512

Block5(3 层 Conv)

  1. 输入:14×14×512 → Conv3-512 ×3 → 14×14×512
  2. MaxPool2×2/2 → 输出 7×7×512

全连接分类头

  1. Flatten 展平:7×7×512 = 25088 一维特征
  2. FC1:4096 神经元 + ReLU + Dropout
  3. FC2:4096 神经元 + ReLU + Dropout
  4. FC3:1000 神经元(ImageNet1000 分类)
  5. Softmax:输出各类别概率

模型代码

import torch from torch import nn from torchsummary import summary class VGG16(nn.Module): def __init__(self): super(VGG16,self).__init__() self.block1 = nn.Sequential( nn.Conv2d(in_channels=1,out_channels=64,kernel_size=3,padding=1), nn.ReLU(), nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2,stride=2) ) self.block2 = nn.Sequential( nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2) ) self.block3 = nn.Sequential( nn.Conv2d(in_channels=128,out_channels=256,kernel_size=3,padding=1), nn.ReLU(), nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2,stride=2) ) self.block4 = nn.Sequential( nn.Conv2d(in_channels=256,out_channels=512,kernel_size=3,padding=1), nn.ReLU(), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2,stride=2) ) self.block5 = nn.Sequential( nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2,stride=2), ) self.block6 = nn.Sequential( nn.Flatten(), nn.Linear(7 * 7 * 512, 256), nn.ReLU(), nn.Dropout(0.5), nn.Linear(256, 128), nn.ReLU(), nn.Dropout(0.5), nn.Linear(128, 10), ) for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, nonlinearity='relu') if m.bias is not None: nn.init.constant_(m.bias, 0) elif isinstance(m, nn.Linear): nn.init.normal_(m.weight, 0, 0.01) if m.bias is not None: nn.init.constant_(m.bias, 0) def forward(self,x): x = self.block1(x) x = self.block2(x) x = self.block3(x) x = self.block4(x) x = self.block5(x) x = self.block6(x) return x if __name__ == "__main__": device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model=VGG16().to(device) summary(model,(1,244,244))

五、VGG 四大核心设计亮点

1. 全程使用 3×3 小卷积核,替代大尺寸卷积

以往 AlexNet 使用 11×11、5×5 大卷积,VGG 全部统一 3×3:

  • 两层 3×3 卷积堆叠感受野等价于 1 层 5×5 卷积;三层 3×3 等价 7×7;
  • 多层非线性激活叠加,特征拟合能力更强;
  • 同等感受野下,3×3 组合参数量更少、计算更高效。

2. 模块化 Block,结构极简易扩展

5 组结构相似的卷积块重复堆叠,只需要调整每个 Block 内卷积层数,就能轻松实现 VGG11/VGG16/VGG19,工程实现、网络修改成本极低。

3. 特征图尺寸规整递减,便于计算与调试

依靠padding=1、stride=1卷积保尺寸,2×2池化stride=2固定减半,每层输出维度可精准推导,调参、可视化特征更友好。

4. 迁移学习能力极强

虽然 VGG 参数量大、推理速度慢,但浅层卷积提取通用边缘、纹理特征,深层提取高级语义特征,至今仍是图像分类、目标检测、语义分割任务中最常用的预训练骨干网络之一。

六、VGG 网络优缺点总结

优点

  1. 结构简单、逻辑清晰,新手友好,极易代码复现;
  2. 小卷积堆叠带来更强非线性表达,分类精度高;
  3. 预训练权重通用性强,迁移学习效果稳定;
  4. 网络分层规律,特征可视化、消融实验方便。

缺点

  1. 参数量巨大(VGG16 1.38 亿),大量参数集中在全连接层,内存占用高;
  2. 全连接层计算量大,推理速度慢,不适合移动端实时部署;
  3. 无残差结构,深度无法无限加深,对比后续 ResNet 上限更低;
  4. 没有分组卷积、空洞卷积等轻量化设计,算力开销大。

七、VGG 实战使用场景

  1. 图像分类 baseline:小型数据集训练首选预训练 VGG,微调成本低;
  2. 目标检测骨干:早期 Faster R-CNN 标配骨干网络;
  3. 图像分割:FCN、U-Net 早期版本使用 VGG 提取编码器特征;
  4. 特征提取:无需分类头,截取卷积层输出做图像检索、相似度匹配。
http://www.jsqmd.com/news/1098658/

相关文章:

  • 2026Word文档过大怎么瘦身,多种压缩Word文件大小实操方法指南
  • 配置外置与敏感隔离:基于 Django-environ 的多环境配置管理策略
  • 基于HarmonyOS 7.0 跨端开发的全球火山活动监测页面实战
  • 性能测试进阶:从压测工具到容量规划的系统工程实践
  • 学 Simulink — 航空航天 270 V DC 高压直流电源变换器的短路保护仿真
  • Prompt工程设计实践:从基础模板到场景化策略
  • 二升三年级暑假特色作业(pdf图文版)
  • Python判断数字?别再用isdigit了,这些坑踩过的人都哭了
  • Pentaho Kettle企业级ETL架构设计与性能优化深度解析
  • 【论文阅读笔记10】小样本充电数据驱动的电池寿命预测——双流ViT与ESA
  • DeepSeek 开始摇人,有点猛啊。
  • 机器人顶刊T-RO收录!同济大学:扔掉标定板,实现全自动在线对齐
  • 抖音批量下载终极指南:3分钟学会高效采集视频、音乐、封面
  • 3步解决华硕笔记本控制难题:G-Helper轻量化性能管理实战指南
  • Xournal++:开源手写笔记软件的跨平台PDF批注解决方案深度解析
  • Magpie终极指南:15种超分辨率算法重塑Windows窗口放大体验
  • YOLO26N 姿态估计 INT8 量化:低算力设备极致优化
  • 最近很火的Loop Engineering到底是什么?
  • uni-app微信小程序开发:核心标签详解(一)
  • 基于HarmonyOS 7.0 跨端开发的宇宙探索科普页面实战
  • 数据中台的血缘管理的制作思路
  • 第六章-扫描路径
  • 3步掌握Twitch掉落自动获取:终极智能挖矿工具完整指南
  • 2026佛山黄金回收白银回收铂金回收旧料回收怎么选?五家高实价铂金白银线下门店测评清单 + 联系方式
  • 视频和音频怎么合并?分享一种免费的方法
  • [hot100]盛最多水的容器
  • 规约驱动开发(SDD)——让规约成为人与 AI 之间的“合同“
  • Pytest+BDD+Playwright:构建现代化Web自动化测试框架的完整指南
  • VS Code 通义灵码报错:调用异常 code=403 解决方案
  • 6.28[a]