深度学习之图像分类(三):VGGNet

news2025/1/18 9:03:34

系列文章目录

本专栏介绍基于深度学习进行图像识别的经典和前沿模型,将持续更新,包括不仅限于:AlexNet, ZFNet,VGG,GoogLeNet,ResNet,DenseNet,SENet,MobileNet,ShuffleNet,EifficientNet,Vision Transformer,Swin Transformer,Visual Attention Network,ConvNeXt, MLP-Mixer,As-MLP,ConvMixer,MetaFormer


VGGNet 文章目录

  • 系列文章目录
  • 前言
  • 一、Vgg网络模型
  • 二、网络贡献总结
    • 1、结构简洁
    • 2、小卷积核
    • 3、小池化核
    • 4、通道数多
    • 5、层数更深、特征图更多
  • 三、 代码实现
  • 总结


前言

2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员Karen Simonyan和Andrew Zisserman研发出了新的深度卷积神经网络:VGGNet,并在ILSVRC2014比赛分类项目中取得了第二名的好成绩(第一名是同年提出的GoogLeNet模型),同时在定位项目中获得第一名。

VGGNet模型通过探索卷积神经网络的深度与性能之间的关系,成功构建了16~19层深的卷积神经网络,并证明了增加网络深度可以在一定程度上提高网络性能,大幅降低错误率。此外,VGGNet具有很强的拓展性和泛化性,适用于其他类型的图像数据。至今,VGGNet仍然被广泛应用于图像特征提取。

VGGNet可以看成是加深版本的AlexNet,都是由卷积层、全连接层两大部分构成。


论文名称:Very deep convolutional networks for large-scale image recognition
论文下载链接:https://arxiv.org/pdf/1409.1556.pdf%E3%80%82
pytorch代码实现:https://github.com/Arwin-Yu/Deep-Learning-Classification-Models-Based-CNN-or-Attention

一、Vgg网络模型

dropout

如上图所示是经典的Vgg16网络模型:

  • 模型接收的输入是彩色图像,数据存储的形状为(B, C, H, W) 分别代表(图像数量,图片色彩通道,图片高度,图片宽度)以上图实例中为(1,3,224,224)
  • 模型的特征提取阶段是不断重复堆叠卷积层和池化层实现的,一共经过5次下采样(图中红颜色的层结构),下采样方式为最大池化。注意:通过调整步长(strdie)和填充(padding),网络中的所有卷积操作都没有改变输入特征图的尺寸。
  • 在最后的顶层设计中,经过三个全连接层实现对图片的分类操作。注意:由于全连接层的存在, 网络只能接收固定大小的图像尺寸。

二、网络贡献总结

1、结构简洁

VGG模型中,所有卷积层的卷积核大小,步长和填充都相同,并且通过使用最大化池对卷积层进行分层。所有隐藏层的激活单元都采用ReLU函数。在最后的顶层设计中,通过三层全连接层和Softmax输出层实现对图像的分类操作。由于其极简且清晰的结构,直到今天VGG也依然被很多工作用于图像的特征提取器,正所谓:大道至简

2、小卷积核

VGGNet中所有的卷积层都使用了小卷积核(3×3)。这种设计有两个优点:一方面,可以大幅减少参数量;另一方面,节省下来的参数可以用于堆叠更多的卷积层,进一步增加了网络的深度和非线性映射能力,从而提高了网络的表达和特征提取能力。

小卷积核是VGG的一个重要特点,虽然VGG是在模仿AlexNet的网络结构,但并没有采用AlexNet中比较大的卷积核尺寸(如7×7),而是通过降低卷积核的大小(3×3),增加卷积子层数来达到同样的性能。

VGG模型中,指出两个3×3的卷积堆叠获得的感受野大小,相当于一个5×5的卷积;而3个3×3卷积的堆叠获取到的感受野相当于一个7×7的卷积。这样可以增加非线性映射,也能很好地减少参数(例如7×7的参数为49个,而3个3×3的参数为27)。

卷积计算结果尺寸(卷积后特征图的size)的计算方式如下。
输入的特征图尺寸为 i \mathrm{i} i, 卷积核的尺寸为 k k k, 步长 (Stride) 为 s s s, 填充 (Padding) 为 p p p, 则输出的特 征图的尺寸 O O O 为。
o = ⌊ i + 2 p − k 2 ⌋ + 1 o=\left\lfloor\frac{i+2 p-k}{2}\right\rfloor+1 o=2i+2pk+1
假设特征图是 28 × 28 28 \times 28 28×28 的, 假设卷记的步长step = 1 =1 =1, padding = 0 =0 =0

  1. 使用一层 5 × 5 5 \times 5 5×5 卷积核, 由 ( 28 − 5 ) / 1 + 1 = 24 (28-5) / 1+1=24 (285)/1+1=24 可得, 输出的特征图尺寸为 24 × 24 24 \times 24 24×24
  2. 使用两层 3 × 3 3 \times 3 3×3 卷积核。
  1. 第一层, 由 ( 28 − 3 ) / 1 + 1 = 26 (28-3) / 1+1=26 (283)/1+1=26 可得, 输出的特征图尺寸为 26 × 26 26 \times 26 26×26
  2. 第二层, 由 ( 26 − 3 ) / 1 + 1 = 24 (26-3) / 1+1=24 (263)/1+1=24 可得, 输出的特征图尺寸为 24 × 24 24 \times 24 24×24
    可以看到最终结果两者相同, 即两个 3 × 3 3 \times 3 3×3 的卷积堆叠获得的感受野大小, 相当于一个 5 × 5 5 \times 5 5×5 的卷积。

3、小池化核

相比AlexNet的3x3的池化核,VGG全部采用2x2的池化核。

4、通道数多

VGG网络第一层的通道数为64,后面每层都进行了翻倍,最多到512个通道。相比较于AlexNet和ZFNet最多得到的通道数是256,VGG 的通道数的进行了翻倍,使得更多的信息可以被卷积操作提取出来。

5、层数更深、特征图更多

网络中,卷积层专注于扩大feature maps的通道数、池化层专注于缩小feature maps的宽和高,使得模型架构上更深更宽的同时,控制了计算量的增加规模。


三、 代码实现

这里给出模型搭建的python代码(基于pytorch实现)。完整的代码是基于图像分类问题的(包括训练和推理脚本,自定义层等)详见我的GitHub:完整代码链接

import torch.nn as nn
import torch
 
class VGG(nn.Module):
    def __init__(self, features, num_classes=1000, init_weights=False):
        super(VGG, self).__init__()
        self.features = features
        self.classifier = nn.Sequential(
            nn.Linear(512*7*7, 4096),
            nn.ReLU(True),
            nn.Dropout(p=0.5),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(p=0.5),
            nn.Linear(4096, num_classes)
        )
        if init_weights:
            self._initialize_weights()

    def forward(self, x):
        # N x 3 x 224 x 224
        x = self.features(x)
        # N x 512 x 7 x 7
        x = torch.flatten(x, start_dim=1)
        # N x 512*7*7
        x = self.classifier(x)
        return x

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                nn.init.xavier_uniform_(m.weight)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.xavier_uniform_(m.weight)
                # nn.init.normal_(m.weight, 0, 0.01)
                nn.init.constant_(m.bias, 0)


def make_features(cfg: list):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == "M":
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            layers += [conv2d, nn.ReLU(True)]
            in_channels = v
    return nn.Sequential(*layers)

# vgg_tiny(VGG11), vgg_small(VGG13), vgg(VGG16), vgg_big(VGG19)
cfgs = {
    'vgg11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],   
    'vgg13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'vgg16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'vgg19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}


def vgg11(num_classes): 
    cfg = cfgs["vgg11"]
    model = VGG(make_features(cfg), num_classes=num_classes)
    return model

def vgg13(num_classes):  
    cfg = cfgs["vgg13"]
    model = VGG(make_features(cfg), num_classes=num_classes)
    return model

def vgg16(num_classes):  
    cfg = cfgs["vgg16"]
    model = VGG(make_features(cfg), num_classes=num_classes)
    return model

def vgg19(num_classes):  
    cfg = cfgs['vgg19']
    model = VGG(make_features(cfg), num_classes=num_classes)
    return model
    
 

总结

VGG是于2014年提出的经典卷积神经网络模型。VGG网络结构简单而规整,由一系列重复的卷积块(Conv Block)和池化块(Pool Block)构成。每个卷积块包含若干个卷积层和激活函数,每个池化块则包含一个池化层。所有的卷积层和池化层都使用相同的卷积核尺寸和步长,从而使得网络结构规整。

此外,VGGNet采用了较小的卷积核尺寸(通常为3×3),这样可以减少模型参数数量,并且通过堆叠多层卷积层来增加模型的深度,从而提高模型的表达能力和分类准确率。在池化层中,VGGNet使用最大池化(Max Pooling)来减少特征图的大小。

VGGNet有多个版本,包括VGG-16、VGG-19等。其中VGG-16包含16个卷积层和3个全连接层,其中VGG-19包含19个卷积层和3个全连接层。这些版本的VGGNet都在ImageNet图像分类竞赛中取得了优异的成绩,并成为了图像分类任务中的经典模型之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/523761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows磁盘空间不够,发现DriverStore文件夹特别大

正想安装一个新的VS2022,但是发现C盘的空间已经不足, 显示为红色了,这样不能安装。只好找一下C盘的空间为什么不足了,后来发现有一个目录特别大,这个目录就是DriverStore文件夹。由于电脑已经运行5年了,也…

Java的线程

介绍线程 线程是系统调度的最小单元,一个进程可以包含多个线程,线程是负责执行二进制指令的。 每个线程有自己的程序计数器、栈(Stack)、寄存器(Register)、本地存储(Thread Local&#xff09…

Linux的基本权限

基本权限 1.权限的概念2.Linux上的用户分类2.1. 如何切换用户? 3.Linux的权限管理3.1. 文件访问者的分类(人)3.2.文件类型和访问权限(文件属性)3.2.1. 文件类型3.2.2. 基本权限 3.3. 文件权限值的表示方法3.3.1. 字符表…

Mac中idea快捷键(Keymap->macOS)

背景: mac:MacBook Pro(13英寸,M2,2022年) 系统版本:12.4 idea快捷键配置:本文快捷键设置基于macOS(Keymap->macOS) 一、常用快捷键 1.commandF 在当前…

java类和对象2

文章目录 一、Java实例变量和类变量二、Java实例方法和类方法三、Java方法重载四、Java this关键字五、Java包六、Java import语句七、Java访问权限八、Java基本类型的类封装九、Java jar文件总结 一、Java实例变量和类变量 实例变量和类变量的定义 在声明成员变量时&#xf…

微信云开发之云函数小例子

环境 微信开发者工具 Stable 1.06.2303220云开发控制台 v1.5.47 概述 云函数即在云端(服务器端)运行的函数,代码运行在云端Node.js中。我们可以使用云函数SDK中提供的数据库和存储API进行数据库和存储的操作。 云函数的独特优势在于与微信…

centos,搭建ftp服务;vsftpd

安装vsftpd 使用yum安装vsftpd: yum install -y vsftpd 配置vsftpd 编辑vsftpd配置文件: vim /etc/vsftpd/vsftpd.conf 以下是一些常见的配置项: anonymous_enableNO local_enableYES write_enableYES local_umask022 dirmessage_enableYE…

职场新人必备:10个写进备忘录的职场tips

作为职场新人,如何快速适应、获得成长和提升自己,是每个人都面临的挑战。在这个竞争激烈的职场中,拥有一些实用的职场tips,可以帮助你更好地应对各种挑战,获得成功。在本文中,我们将分享10个写进备忘录的职…

es8388 驱动详解

音频的基本框架 分为三个部分: 1) 整体的绿框,为machine,例如你的PC等,负责图中 “线”的部分的关联,及黄色连接器的管理。也就是说不属于 paltform和codec管理的部分,都划归machine管理。 对应…

【Python socket】零基础也能轻松掌握的学习路线与参考资料

Python socket是Python程序语言中与网络编程密切相关的库之一,可以让程序员在网络世界中建立服务和客户端之间的连接。Python socket提供了一系列关键的概念和方法,让用户能够轻松地构建基于网络的程序,如基于TCP和UDP的应用程序。学习Python…

图(Graph)

Graph 图由顶点(vertex /ˈvɜːrteks/)和边(edge /edʒ/)组成的一种结构。 顶点的集合V,边的集合是E,所以图记为G (V,E) 总结: 顶点是一维数组,而边是二维数组; 假如顶点…

Pycharm无法添加Conda新建的虚拟环境

Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can’t find python path to use, will use conda run instead 1.问题描述🔍 在PyCharm中,依次单击File>Settings>P…

Netty核心技术一--Netty介绍和应用场景

1. 学习要求 要求已经掌握了 Java 编程, 主要技术构成: Java OOP 编程、Java 多线程编程、JavaIO 编程 、Java 网络编程、常用的Java 设计模式(比如观察者模式,命令模式,职责链模式 )、常用的数据结构(比如 链表) 2 Netty的介绍…

C++: 计时器类的设计和实现

文章目录 1. 目的2. 功能列表3. 基础功能:获取耗时4. API 设计: Timer 类5. 单元测试6. API 实现 1. 目的 使用 C Class 的形式,封装原本 C语言的获取时间的函数,提供更容易使用的计时器调用。 使用 C03,原因是和先前的线程安全队…

ATT-ACK靶场渗透(一)

开启内网环境 kali攻击机ip为 192.168.88.156 主机发现、端口扫描 进行主机发现 nmap -sS 192.168.88.156/24 -Pn 192.168.88.1和192.168.88.2可能为网关之类的,不管 weblogic漏洞利用 192.168.88.182开放了80端口和7001(weblogic)端口…

超越预期:ConvNeXt技术催生YOLOv5目标检测巨变 ,实现超准确率

目录 引言一、ConvNeXt的介绍1、目标检测的重要性2、YOLOv5的介绍3、ConvNeXt原理和特点4、ConvNeXt结构 二、相关研究综述1、目标检测的基础原理和流程2、YOLOv5的特点与局限性3、ConvNeXt技术在目标检测中的应用现状 三、ConvNeXt在YOLOv5中的应用与改进1、安装PyTorch和torc…

阿里Java工程规约(来源阿里)

一、应用分层 1.开放接口层: 可直接封装 Service 接口暴露成 RPC 接口;通过 Web 封装成 http 接口;网关控制层等。 2.终端显示层: 各个端的模板渲染并执行显示层。当前主要是 velocity 渲染,JS 渲染,JSP 渲…

[golang gin框架] 33.Gin 商城项目- 微信支付操作相关功能讲解

一.微信支付准备工作 准备工作 申请条件: 个体工商户 、企业、政府及事业单位 PC网站接入支付官网,其他(app,小程序,公众号等)可参考 PC网站接入支付 需要获取内容 appid:应用 APPID(必须配置,开户邮件中可查看) MCHID&#xff1a…

Java Socket和ServerSocket 使用

在Java中,Socket和ServerSocket是用于创建网络连接的重要类。Socket类用于创建客户端套接字,而ServerSocket类用于创建服务器套接字。在本文中,我们将讨论Socket和ServerSocket的作用、使用方法以及相关代码示例。 Socket的作用 Socket是Jav…

【连续介质力学】张量的并矢和性质1

张量的代数操作 并矢 Dyadic 两个向量的张量积是一个并矢,得到一个二阶张量 u ⃗ v ⃗ u ⃗ ⨂ v ⃗ A \vec u \vec v \vec u \bigotimes \vec v A u v u ⨂v A 其中, ⨂ \bigotimes ⨂是张量乘积,任意张量可以表示成并矢的线性组合 …