【深度学习-图像分类】03 - VGG 论文学习与总结

论文地址:VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION

论文学习

1. 摘要

  • 这篇论文探讨了在大规模图像识别任务中,卷积神经网络(ConvNets)深度对其准确性的影响。作者的主要贡献是对不断增加深度的网络进行了全面评估,这些网络使用了非常小的(3x3)卷积滤波器。研究发现,通过将网络深度增加到16到19层,可以显著提高性能,超越了之前的艺术水平配置。(通过卷积神经网络的加深可以显著提高性能)
  • 这些发现是作者在2014年ImageNet挑战中提交作品的基础,他们的团队在定位和分类跟踪中分别获得了第一和第二名。此外,作者还展示了他们的表示(网络学到的特征)在其他数据集上也能很好地泛化,并取得了最先进的结果。为了促进深度视觉表示在计算机视觉领域的进一步研究,作者公开了他们表现最好的两个ConvNet模型。(验证通过卷积神经网络结构上的加深可以提高性能这个猜想)

2. 引言

  1. 卷积网络的成功应用
    • 引言部分首先强调了卷积网络(ConvNets)在大规模图像和视频识别领域的成功应用。特别提到了一些关键的研究,如Krizhevsky等人在2012年的工作,这些研究标志着深度学习在视觉识别任务中的重要突破。
  2. 公共图像库和高性能计算系统的作用
    • 论文提到了大型公共图像库(如ImageNet)和高性能计算系统(如GPU或大规模分布式集群)在推动深度视觉识别架构发展中的作用。
  3. ImageNet挑战赛的影响
    • 引言中还讨论了ImageNet大规模视觉识别挑战(ILSVRC)对于几代大规模图像分类系统的影响,从高维浅层特征编码到深度卷积网络。
  4. 卷积网络架构的改进尝试
    • 论文回顾了在Krizhevsky等人的原始架构基础上,为了提高准确性而进行的各种改进尝试,包括调整卷积层的接收窗口大小和步幅,以及在整个图像和多个尺度上密集训练和测试网络。
  5. 深度在卷积网络设计中的重要性
    • 引言部分特别强调了深度在卷积网络架构设计中的重要性。论文的主要目标是通过增加更多的卷积层来探索深度的极限,并使用非常小的(3x3)卷积滤波器。
  6. 研究动机和目标
    • 论文的动机是验证通过增加网络深度是否能显著提高图像识别的性能。目标是开发出能够在ILSVRC分类和定位任务上取得最先进性能的深度卷积网络架构。

3. ConvNet配置

  1. 统一的ConvNet架构设计
    • 论文中所有的ConvNet配置都遵循了一套统一的设计原则。这些原则受到了之前研究的启发,特别是Ciresan等人(2011年)和Krizhevsky等人(2012年)的工作。
  2. 架构细节
    • 训练时,ConvNets的输入是固定大小的224x224 RGB图像。唯一的预处理步骤是从每个像素中减去在训练集上计算得到的平均RGB值。
    • 图像通过一系列卷积层进行处理,这些层使用非常小的3x3的感受野。在某些配置中,还使用了1x1的卷积滤波器,作为输入通道的线性变换。
    • 卷积层之后是一系列最大池化层,但并不是每个卷积层后都跟有池化层。
    • 网络的最后是三个全连接层,前两个各有4096个通道,第三个用于1000类ILSVRC分类,因此有1000个通道。
  3. 深度和宽度的平衡
    • 论文中的网络深度从11层(网络A)到19层(网络E)不等。卷积层的宽度(通道数)从第一层的64开始,每经过一个最大池化层就翻倍,直到达到512。
  4. 网络配置的变体
    • 论文详细描述了几种不同的网络配置(标记为A到E),每种配置都在通用设计的基础上增加了更多的层。
    • 这些配置的主要区别在于网络的深度,即卷积层和全连接层的数量。
  5. 配置与先前工作的比较
    • 作者讨论了他们的ConvNet配置与之前在ILSVRC-2012和ILSVRC-2013比赛中表现最佳的模型之间的区别。
    • 与先前模型相比,本文的网络使用了更小的感受野,并在整个网络中保持了较小的步幅和较多的卷积层。

4. 分类框架

  1. 训练细节
    • 训练过程基本遵循了Krizhevsky等人(2012年)的方法,但在从多尺度训练图像中采样输入裁剪方面有所不同。
    • 使用小批量梯度下降法进行优化,批量大小设为256,动量为0.9。
    • 采用L2权重衰减(权重衰减系数设为5e-4)和前两个全连接层的dropout(dropout比率为0.5)进行正则化。
    • 初始学习率设为1e-2,当验证集准确率不再提高时,学习率减少10倍,总共减少3次,学习过程在大约370K次迭代(74个epoch)后停止。
  2. 网络初始化
    • 网络权重的初始化非常重要,因为不良的初始化可能导致深度网络中梯度的不稳定。
    • 作者首先训练了较浅的网络A,然后使用它来初始化更深网络的部分层。
    • 对于随机初始化的层,权重从均值为0、方差为1e-2的正态分布中采样,偏置项初始化为0。
  3. 训练图像的尺寸和增强
    • 训练图像首先被等比例缩放,然后从中随机裁剪出224x224的图像作为网络输入。
    • 进行了图像水平翻转和随机RGB颜色偏移的数据增强。
  4. 多尺度训练
    • 论文考虑了两种设置训练尺度S的方法:固定S和多尺度训练,后者通过从一定范围内随机采样S来模拟不同大小的对象。

5. 分类实验

  1. 实验数据集
    • 实验主要在ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 2012数据集上进行,该数据集包含1000个类别,超过120万张训练图像、5万张验证图像和15万张测试图像。
  2. 单尺度评估
    • 对不同深度的ConvNet模型在单一尺度上进行评估。测试图像的尺寸被固定,与训练时相同。
      实验结果显示,随着网络深度的增加,分类错误率显著下降。特别是,更深的网络(如配置D和E)比浅层网络有更好的性能。
  3. 多尺度评估
    • 在测试时考虑了多个尺度,以提高性能。这包括在不同尺寸的图像上运行模型,并将结果进行平均。
    • 使用多尺度评估可以进一步提高分类准确率。
  4. 多裁剪评估
    • 除了全图评估外,还使用了多裁剪方法来提高准确率。这种方法包括在图像的不同位置进行裁剪,并对结果进行平均。
  5. ConvNet融合
    • 通过结合多个不同配置的ConvNet模型的输出来提高性能。这种融合方法利用了不同模型的互补性。
  6. 与最先进技术的比较
    • 将实验结果与当时的最先进技术进行了比较。论文中的深度ConvNet模型在分类任务上达到了新的最佳性能。
  7. 实验结论
    • 实验结果强调了网络深度对于提高大规模图像分类性能的重要性。更深的网络能够学习到更丰富和更具判别性的特征表示。

6. 结论

  1. 深度对性能的显著影响
    • 论文的结论部分首先强调了在大规模图像分类中,网络深度对提高性能的显著影响。通过实验验证,作者展示了更深的网络结构(最多19层权重层)能够显著提高分类准确率。
  2. 传统ConvNet架构的有效性
    • 作者指出,尽管他们的网络架构非常深,但仍然基于传统的ConvNet架构。这表明,通过增加深度而不是改变基本架构,就能实现显著的性能提升。
  3. 泛化能力
    • 结论中还提到,这些深度网络不仅在ImageNet挑战中表现出色,而且在其他数据集上也展现了良好的泛化能力。这表明深度网络学到的特征具有广泛的适用性。
  4. 对未来研究的启示
    • 论文的结论强调了深度在视觉表示中的重要性,并对未来的研究提供了方向,即探索更深的网络架构以及它们在各种视觉识别任务中的应用。
  5. 公开模型的贡献
    • 作者提到,他们已经公开了最优表现的两个模型,以促进深度视觉表示在计算机视觉领域的进一步研究。

这篇论文《VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION》的创新点以及主要贡献如下:

创新点:深度网络架构

  1. 引入非常深的网络架构: 论文的主要创新之一是提出了非常深的卷积网络架构,最多达到19层权重层,这在当时是一个显著的进步,因为之前的网络通常深度较浅。
  2. 使用小型卷积滤波器: 论文中的网络使用了小尺寸(3x3)的卷积滤波器,这与当时常用的较大滤波器不同。这种设计允许在增加深度的同时控制参数数量,提高了网络的学习能力和效率。

主要贡献:性能提升和影响

  1. 显著提高图像分类性能: 通过实验,论文证明了更深的网络架构在ImageNet数据集上能够显著提高图像分类的准确率,这推动了深度学习在图像识别领域的发展。
  2. 网络泛化能力的验证: 论文还展示了这些深度网络在其他数据集上的良好泛化能力,表明深度学习模型学到的特征具有广泛的适用性。
  3. 推动深度学习研究: 论文的发表促进了深度学习在计算机视觉领域的研究,特别是在探索更深网络架构的可能性和有效性方面。

VGG

在这里插入图片描述
在这里插入图片描述

  1. 输入层:网络接收一个224 x 224 x 3的输入图像,这意味着图像宽度为224像素,高度为224像素,具有3个颜色通道(红色、绿色和蓝色)。

  2. 第一和第二个卷积块:输入图像首先经过两个3x3的卷积层,每个层的深度为64。每个卷积层后面都接一个ReLU激活函数。该块最后是一个2x2滤波器和步长为2的最大池化层,将尺寸减半到112 x 112 x 64。

  3. 第三和第四个卷积块:每个块由两个3x3的卷积层组成。第三个块的深度增加到128,第四块进一步增加到256。每个卷积层后面都接ReLU激活函数。每个块最后都有一个最大池化层,同样的规格,将尺寸缩小到56 x 56 x 128和28 x 28 x 256。

  4. 第五和第六个卷积块:这两个块各包含三个3x3的卷积层。第五块的深度保持为256,而第六块增加到512。如前所述,每个卷积层后面都接一个ReLU激活,每个块结束时有一个最大池化层,将尺寸进一步减小到14 x 14 x 512,然后是7 x 7 x 512。

  5. 全连接层:将最后一个池化层的输出扁平化后,网络过渡到三个全连接层。前两个全连接层各有4096个单元,应用了ReLU激活函数。此外,第一个全连接层后面接一个dropout层以防止过拟合。

  6. 输出层:最后一个全连接层有1000个单元,对应1000个类别,后面接一个softmax函数来得到类别的概率分布。

  7. 目标:网络产生一个分类输出,在提供的图片的上下文中,对应的类别为“汽车”。

代码实现

from typing import cast

import torch
from torch import nn
from torch.hub import load_state_dict_from_url


class VGG(nn.Module):
    def __init__(
            self,
            features,
            num_classes=1000,
            init_weights=True,
            dropout=0.5
    ):
        """
        :param features: 特征提取层,也就是vgg块组成
        :param num_classes: 输出类别数量 默认1000
        :param init_weights: 是否参数初始化 默认是True
        :param dropout: drop正则化概率 默认是0.5
        """
        super().__init__()
        self.features = features
        self.avgpool = nn.AdaptiveAvgPool2d((7 * 7))
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(True),
            nn.Dropout(p=dropout),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(p=dropout),
            nn.Linear(4096, num_classes),
        )

        if init_weights:
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
                    if m.bias is not None:
                        nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.Linear):
                    nn.init.normal_(m.weight, 0, 0.01)
                    nn.init.constant_(m.bias, 0)

    def forward(self,x ):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

def make_layers(cfg, batch_norm=False):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            v = cast(int, v)
            conv2d = nn.Conv2d(in_channels=in_channels, out_channels= v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(num_features=v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
        in_channels = v
    return nn.Sequential(*layers)

cfgs = {
    "A": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
    "B": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
    "D": [64, 64, "M", 128, 128, "M", 256, 256, 256, "M", 512, 512, 512, "M", 512, 512, 512, "M"],
    "E": [64, 64, "M", 128, 128, "M", 256, 256, 256, 256, "M", 512, 512, 512, 512, "M", 512, 512, 512, 512, "M"],
}
model_config = {
    "VGG-11": {
        "cfg" : "A",
        "model_url" : {
            "normal" : "https://download.pytorch.org/models/vgg11-8a719046.pth",
            "bn" : "https://download.pytorch.org/models/vgg11_bn-6002323d.pth"
        }
    },
    "VGG-13": {
        "cfg" : "B",
        "model_url" : {
            "normal" : "https://download.pytorch.org/models/vgg13-19584684.pth",
            "bn" : "https://download.pytorch.org/models/vgg13_bn-abd245e5.pth"
        }
    },
    "VGG-16": {
        "cfg" : "D",
        "model_url" : {
            "normal" : "https://download.pytorch.org/models/vgg16-397923af.pth",
            "bn" : "https://download.pytorch.org/models/vgg16_bn-6c64b313.pth"
        }
    },
    "VGG-19": {
        "cfg" : "E",
        "model_url" : {
            "normal" : "https://download.pytorch.org/models/vgg19-dcbb9e9d.pth",
            "bn" : "https://download.pytorch.org/models/vgg19_bn-c79401a0.pth"
        }
    },
}
def vgg(model_name, num_classes=1000, pretrained=True, batch_norm=True):
    config = model_config[model_name]
    model = VGG(features=make_layers(cfg=cfgs[config['cfg']], batch_norm=batch_norm))
    if pretrained:
        if batch_norm:
            state_dict = load_state_dict_from_url(
                url = config["model_url"]["bn"],
                model_dir="./pretrained_model",
                progress=True
            )
        else:
            state_dict = load_state_dict_from_url(
                url=config["model_url"]["normal"],
                model_dir="./pretrained_model",
                progress=True
            )
        model.load_state_dict(state_dict=state_dict, strict=False)
    if num_classes != 1000:
        model.classifier[-1] = nn.Linear(in_features=4096, out_features=num_classes)
    return model

以上内容旨在记录自己的学习过程以及复习,如有错误,欢迎批评指正,谢谢阅读。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mybatis-flex笔记

MyBatis-Flex 的增删改功能 - MyBatis-Flex 官方网站https://mybatis-flex.com/zh/base/add-delete-update.html 代码https://gitee.com/hntianshu/mybatis-flex-test 一 新增数据 不忽略 null 值。 就是允许有null 忽略null 就是不允许有null BaseMapper 的接口提供了 inser…

Vue3-33-路由-路由的别名配置 alias

别名的作用 路由中的别名配置,可以实现 多个路径 对应 同一个路由。 例如 : 路由的路径是 /a; 配置别名为 : /a2; 则 访问 /a 或 /a2 的时候,都可以访问到 同一个组件。 别名的特点 关键字 : alias 当通过别名进行路由…

将 Python 和 Rust 融合在一起,为 pyQuil® 4.0 带来和谐

文章目录 前言设定方向从 Rust 库构建 Python 软件包改装 pyQuil异步困境回报:功能和性能结论 前言 pyQuil 一直是在 Rigetti 量子处理单元(QPUs)上构建和运行量子程序的基石,通过我们的 Quantum Cloud Services(QCS™…

擎创技术流 |如何使用eBPF监控NAT转换

一、NAT简介 Linux NAT(Network Address Translation)转换是一种网络技术,用于将一个或多个私有网络内的IP地址转换为一个公共的IP地址,以便与互联网通信。 图源于网络 在k8s业务场景中,业务组件之间的关系十分复杂. …

【LabVIEW FPGA入门】创建第一个LabVIEW FPGA程序

本教程仅以compactRIO(FPGA-RT)举例 1.系统配置 1.1软件安装 FPGA-RT 1. LabVIEW Development System (Full or Professional) 2. LabVIEW Real-Time Module 3. LabVIEW FPGA Module 4. NI-RIO drivers 1.2硬件配置 1.使用线缆连接CompactRIO至主机…

OpenHarmony之HDF驱动框架

概述 HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在…

鸟类识别与分类

Littro 双波段T型云台成像AI一体机是利卓公司结合了红外热成像、可见光相机与边缘计算为一体的整机产品。 产品同时支持双波段成像,基于瞳赋Tofu3智能识别模块的AI算法可以克服因光线不足、背景复杂造成的诸多不利因素,完成目标检测、识别、跟踪等多种功…

RabbitMQ集群的简单说明

1.普通集群(副本集群) 当集群中某一时刻master主节点宕机,可以对master中Queue中的消息进行备份。而就算master宕机了,从节点不会对外提供服务,等到master节点恢复后,系统才会恢复正常。 主从架构的缺点是队列中的消息只是位于主节…

51单片机之LED灯

51单片机之LED灯 🌴前言:🏮点亮LED灯的原理💘点亮你的第一个LED灯💘点亮你的八个LED灯 📌让LED灯闪烁的原理🎽 LED灯的闪烁🏓错误示范1🏓正确的LED闪烁代码应该是这样&am…

玩转数据世界:跨工作空间的安全授权与高效查询

前言 随着数字化时代的来临,数据已经成为了企业和组织的核心资产。如何安全有效地管理和利用这些数据,成为了各行业共同面临的挑战。尤其是在多个工作空间或部门之间,数据的共享、查询和分析往往涉及到复杂的权限管理,影响组织的…

移动CRM系统有哪些具体的应用场景?移动CRM好用吗?

大家好我是卡林,最近杭州亚运会盛大举办,外国友人在打卡各地美食景点的同时也体会到了移动支付的乐趣。在智能手机全面普及的今天,移动CRM系统的应用也越来越广泛,移动CRM系统的应用场景有哪些?移动办公、签到打卡、销…

【C语言】Linux socket 编程

一、Socket 通信过程 在 Linux 系统中,socket 是一种特殊的文件描述符,用于在网络中的不同主机间或者同一台主机中的不同进程间进行双向通信。它是通信链路的端点,可以看作是网络通信的接口。Socket 通信过程主要分为以下几个步骤&#xff1a…

【算法】利用分治思想解算法题:快排、归并、快速选择实战(C++)

1. 分治思想 介绍 分治法将问题划分成多个相互独立且相同或类似的子问题,然后递归地解决每个子问题,并将结果合并以得到原始问题的解。 分治思想通常包含以下三个步骤: 分解:将原始问题划分成多个规模较小、相互独立且类似的子…

企业如何利用好数据,让数据真正成为数据资产?数据资产管理应该怎样建设?

数字化时代,数据已经成为了个人、机构、企业乃至国家的重要战略资产。 近日,财政部正式对外发布《企业数据资源相关会计处理暂行规定》,并自 2024 年 1 月 1 日开始施行。数据资产入表政策落地节奏超预期,标志着国家把数据作为生…

如何用python实时监控股票,并且持续扫描大盘?

用 Python 抓取分析股市数据很简单!只用短短几行代码,就能实现策略制定到交易信号生成。 一、数据准备 在分析的最开始,需要获取数据。本文中将以沪深 300 指数为标的进行分析(包含日期、开高低收价、成交量、成交额字段&#xf…

MySQL之四大引擎、账号管理以及建库认识

目录 一、数据库存储引擎(发动机) 1.1、认识引擎 1.2、查看存储引擎 1.3、引擎常识 1.4、support字段说明 1.5、四大引擎 二、数据库管理 2.1、元数据库介绍: 2.2、分类: 2.3、增删改查以及使用操作 2.4、权限 三、数…

【面试高频算法解析】算法练习2 回溯

目录 前言算法解析练习题组合总和全排列II单词搜索 前言 本篇章开放目的是按算法类型学习算法,学习对应算法理论,并通过练习一些经典算法题深入理解这类算法,避免出现刷了很多算法题,还是一知半解的状态 算法解析 回溯&#xff…

UDP通信(服务器-客户端)

一、 UDP服务器-客户端通信 UDP(User Datagram Protocol)是一种面向无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP(Transmission Control Protocol)不同,UDP不建立连接,…

FusionAccess配置Lite AD

1、Lite AD的安装及配置 Lite AD流程: (1)创建一个新的Windows 10,安装tools,再安装ITA组件(安装Lite AD会自动安装VAG/VLB) (2)创建一个新的Windows 10,安…

线性规划中解的关系

写于:2024年1月2日星期二 修改于: 本文从两个角度对线性规划中的解做划分,角度一是将解划为基解、基可行解、可行解;角度二是将解划分为无可行解、无界解、最优解(唯一和无穷多)。同时,详细描述…