经典神经网络(3)Vgg-Net及其在Fashion-MNIST数据集上的应用

news2024/11/20 2:43:28

经典神经网络(3)VGG_使用块的网络

1 VGG的简述

1.1 VGG的概述

  1. VGG-Net 是牛津大学计算机视觉组和DeepMind公司共同研发一种深度卷积网络,并且在2014年在ILSVRC比赛上获得了分类项目的第二名和定位项目的第一名。通过使⽤循环和⼦程序,可以很容易地在任何现代深度学习框架的代码中实现这些重复的架构。
  2. VGG-Net 的主要贡献是:
    • 证明了小尺寸卷积核(3x3 )的深层网络要优于大尺寸卷积核的浅层网络。
    • 证明了深度对网络的泛化性能的重要性。
    • 块的使⽤导致定义的网络⾮常简洁。使用块可以有效地设计复杂的网络。
    • 验证了尺寸抖动scale jittering 这一数据增强技术的有效性。
  3. VGG-Net 最大的问题在于参数数量,VGG-19 基本上是参数数量最多的卷积网络架构。

1.2 AlexNet和VGG的对比

在这里插入图片描述

  • 与AlexNet、LeNet⼀样,VGG⽹络可以分为两部分:第⼀部分主要由卷积层和汇聚层组成,第⼆部分由全连接层组成。

  • VGG神经网络第⼀部分由几个VGG块连接而成。全连接模块则与AlexNet中的相同。

  • AlexNet 相比,VGG-Net 在第一个全连接层的输入feature map 较大:7x7 vs 6x6512 vs 256

1.3 VGG神经网络的5组结构

VGG-Net 一共有五组结构(分别表示为:A~E ), 每组结构都类似,区别在于网络深度上的不同。

  • 结构中不同的部分用黑色粗体给出。

  • 卷积层的参数为convx-y,其中x 为卷积核大小,y 为卷积核数量。

    如:conv3-64 表示 643x3 的卷积核。

  • 卷积层的通道数刚开始很小(64通道),然后在每个池化层之后的卷积层通道数翻倍,直到512。

  • 每个卷积层之后都跟随一个ReLU激活函数。

在这里插入图片描述

  • 输入层:固定大小的224x224RGB 图像。

  • 卷积层:卷积步长均为1。

    • 填充方式:填充卷积层的输入,使得卷积前后保持同样的空间分辨率。

      • 3x3 卷积:same 填充,即:输入的上下左右各填充1个像素。
      • 1x1 卷积:不需要填充。
    • 卷积核尺寸:有3x31x1 两种。

      • 3x3 卷积核:这是捕获左右、上下、中心等概念的最小尺寸。

      • 1x1 卷积核:用于输入通道的线性变换。

        在它之后接一个ReLU 激活函数,使得输入通道执行了非线性变换。

  • 池化层:采用最大池化。

    • 池化层连接在卷积层之后,但并不是所有的卷积层之后都有池化。
    • 池化窗口为2x2,步长为 2 。
  • 网络最后四层为::三个全连接层 + 一个softmax 层。

    • 前两个全连接层都是 4096个神经元,第三个全连接层是 1000 个神经元(因为执行的是 1000 类的分类)。
    • 最后一层是softmax 层用于输出类别的概率。
  • 所有隐层都使用ReLU 激活函数。

1.4 VGG神经网络5组结构的参数量

其中第一个全连接层的参数数量为:7x7x512x4096=1.02亿 ,因此网络绝大部分参数来自于该层。

网络A , A-LRNBCDE
参数数量1.13亿1.33亿1.34亿1.38亿1.44

1.5 VGG-11的实现

import torch.nn as nn
import torch

'''
原始VGG⽹络有5个卷积块,其中前两个块各有⼀个卷积层,后三个块各包含两个卷积层。
第⼀个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。
由于该⽹络使⽤8个卷积层和3个全连接层,因此它通常被称为VGG-11。
'''
class Vgg11Net(nn.Module):


    def __init__(self):
        super().__init__()
        self.model = self.vgg()

    
    def forward(self, X):
        X = self.model(X)
        return X

    def vgg(self):
        conv_blks = []
        # 输入通道的数量,初始化为1
        in_channels = 1

        # 卷积层部分,一共有5个vgg块,其中前两个块各有⼀个卷积层,后三个块各包含两个卷积层
        conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
        for (num_convs, out_channels) in conv_arch:
            # 添加vgg块
            conv_blks.append(self.vgg_block(num_convs, in_channels, out_channels))
            in_channels = out_channels

        return nn.Sequential(
            *conv_blks,
            nn.Flatten(),
            # 全连接层部分,和AlexNet一致
            # 第一个全连接层的参数数量为:7x7x512x4096=1.02亿,因此网络绝大部分参数来自于该层
            nn.Linear(512 * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),
            nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
            nn.Linear(4096, 10)
        )




    def vgg_block(self,num_convs,in_channels,out_channels):

        """
        :param num_convs:    卷积层的数量
        :param in_channels:  输⼊通道的数量
        :param out_channels: 输出通道的数量
        :return: vgg块
        """
        layers = []
        for _ in range(num_convs):
            # 卷积层
            layers.append(
                # 填充方式:填充卷积层的输入,使得卷积前后保持同样的空间分辨率
                nn.Conv2d(in_channels,out_channels,kernel_size=3,padding=1)
            )
            layers.append(nn.ReLU())
            in_channels = out_channels

        # 汇聚层
        layers.append(nn.MaxPool2d(kernel_size=2,stride=2))

        return nn.Sequential(*layers)



if __name__ == '__main__':
    net = Vgg11Net()
    # 测试神经网络是否可运行
    # inputs = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    # outputs = net(inputs)
    # print(outputs.shape)
    # 查看每一层输出的shape
    X = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    for layer in net.model:
        X = layer(X)
        print(layer.__class__.__name__, 'output shape:', X.shape)
# 1、5个卷积块,其中前两个块各有⼀个卷积层,后三个块各包含两个卷积层。
# 第⼀个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。
Sequential output shape: torch.Size([1, 64, 112, 112])
Sequential output shape: torch.Size([1, 128, 56, 56])
Sequential output shape: torch.Size([1, 256, 28, 28])
Sequential output shape: torch.Size([1, 512, 14, 14])
Sequential output shape: torch.Size([1, 512, 7, 7])

# 2、和AlexNet一样的3个全连接层
Flatten output shape: torch.Size([1, 25088])
Linear output shape: torch.Size([1, 4096])
ReLU output shape: torch.Size([1, 4096])
Dropout output shape: torch.Size([1, 4096])

Linear output shape: torch.Size([1, 4096])
ReLU output shape: torch.Size([1, 4096])
Dropout output shape: torch.Size([1, 4096])

Linear output shape: torch.Size([1, 10])

2 VGG论文的创新点

论文的下载地址为:https://arxiv.org/pdf/1409.1556.pdf

2.1 权重的初始化

由于网络深度较深,因此网络权重的初始化很重要,设计不好的初始化可能会阻碍学习。

  • 论文的权重初始化方案为:先训练结构A 。当训练更深的配置时,使用结构A 的前四个卷积层和最后三个全连接层来初始化网络,网络的其它层被随机初始化。
  • 作者后来指出:可以通过 Xavier均匀初始化来直接初始化权重而不需要进行预训练。

2.2 局部响应归一化层LRN

  • 分类误差随着网络深度的增加而减小。
  • A-LRNA 的比较发现:局部响应归一化层LRN 对于模型没有任何改善。

2.3 通道像素零均值化

  • 先统计训练集中全部样本的通道均值:所有红色通道的像素均值a 、所有绿色通道的像素均值b 、所有蓝色通道的像素均值c
  • 对每个样本:红色通道的每个像素值减去a ,绿色通道的每个像素值减去b ,蓝色通道的每个像素值减去c。

论文中还有多尺度训练、多尺度测试等内容,有兴趣的可以阅读一下原文。

3 VGG-11在Fashion-MNIST数据集上的应用示例

3.1 创建VGG-11网络模型

注意:由于VGG-11⽐AlexNet计算量更⼤,因此我们构建了⼀个通道数较少的⽹络,⾜够⽤于训练Fashion-MNIST数据集。

import torch.nn as nn
import torch

'''
原始VGG⽹络有5个卷积块,其中前两个块各有⼀个卷积层,后三个块各包含两个卷积层。
第⼀个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。
由于该⽹络使⽤8个卷积层和3个全连接层,因此它通常被称为VGG-11。
'''
class Vgg11Net(nn.Module):


    def __init__(self):
        super().__init__()
        self.model = self.vgg()


    def forward(self, X):
        X = self.model(X)
        return X

    def vgg(self):
        conv_blks = []
        # 输入通道的数量,初始化为1
        in_channels = 1

        # 卷积层部分,一共有5个vgg块,其中前两个块各有⼀个卷积层,后三个块各包含两个卷积层
        conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
        # 1、由于VGG-11⽐AlexNet计算量更⼤,因此我们构建了⼀个通道数较少的⽹络,⾜够⽤于训练Fashion-MNIST数据集。
        small_conv_arch = [(pair[0], pair[1] // 4) for pair in conv_arch]
        for (num_convs, out_channels) in small_conv_arch:
            # 添加vgg块
            conv_blks.append(self.vgg_block(num_convs, in_channels, out_channels))
            in_channels = out_channels

        return nn.Sequential(
            *conv_blks,
            nn.Flatten(),
            # 全连接层部分,和AlexNet一致
            # 2、注意,这里从512改为128
            nn.Linear(128 * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),
            nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
            nn.Linear(4096, 10)
        )




    def vgg_block(self,num_convs,in_channels,out_channels):

        """
        :param num_convs:    卷积层的数量
        :param in_channels:  输⼊通道的数量
        :param out_channels: 输出通道的数量
        :return: vgg块
        """
        layers = []
        for _ in range(num_convs):
            # 卷积层
            layers.append(
                nn.Conv2d(in_channels,out_channels,kernel_size=3,padding=1)
            )
            layers.append(nn.ReLU())
            in_channels = out_channels

        # 汇聚层
        layers.append(nn.MaxPool2d(kernel_size=2,stride=2))

        return nn.Sequential(*layers)



if __name__ == '__main__':
    net = Vgg11Net()
    # 测试神经网络是否可运行
    # inputs = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    # outputs = net(inputs)
    # print(outputs.shape)
    # 查看每一层输出的shape
    X = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    for layer in net.model:
        X = layer(X)
        print(layer.__class__.__name__, 'output shape:', X.shape)

3.2 读取Fashion-MNIST数据集

其他所有的函数,与经典神经网络(1)LeNet及其在Fashion-MNIST数据集上的应用完全一致。

'''
Fashion-MNIST图像的分辨率(28×28像素)低于ImageNet图像。为了解决这个问题,增加到224×224
'''
batch_size = 128
train_iter,test_iter = get_mnist_data(batch_size,resize=224)

3.3 在GPU上进行模型训练

from _03_Vgg11Net import Vgg11Net

# 初始化模型
net = Vgg11Net()

lr, num_epochs = 0.05, 10
train_ch(net, train_iter, test_iter, num_epochs, lr, try_gpu())

在这里插入图片描述
注:Vgg-Net用GPU才能跑,如果自己电脑没有合适的GPU,可以参考下面文章进行租借

AutoDL平台租借GPU详解

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

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

相关文章

JavaEE(系列6) -- 多线程(解决线程不安全系列1-- 加锁(synchronized)与volatile)

首先我们回顾一下上一章节引起线程不安全的原因 本质原因:线程在系统中的调度是无序的/随机的(抢占式执行) 1.抢占式执行 2.多个线程修改同一个变量. 一个线程修改一个变量>安全 多个线程读取同一个变量>安全 多个线程修改不同的变量>安全 3.修改操作,不是原子的.(最…

容器安装Datax+Datax-web2.1(一)

目录 简介1、安装Datax-web2.1.11)安装docker-compose2)创建Datax-web和MySQL容器 2、安装Datax-web2.1.21)安装MySQL2)初始化数据3)安装datax和datax-web4)浏览器登录 DataxDatax-web2.1实现MySQL数据库数…

LeetCode 21. 合并两个有序链表 | C++语言版

LeetCode 21. 合并两个有序链表 | C语言版 LeetCode 36: 两个链表的第一个公共结点题目描述解题思路思路一:使用前缀和代码实现运行结果参考文章: 思路二:减少遍历节点数代码实现运行结果参考文章: LeetCode 36&#x…

CANoe-如何在Trace窗口显示SYN和FIN报文、同一条以太网报文在Trace窗口中的多条显示

1、如何在Trace窗口显示SYN和FIN报文 当我们使用CANoe实现TCP通信时,希望在Trace窗口直观显示报文的类型:SYN、ACK、FIN。显然Trace窗口也是支持这样的功能的。但很多时候由于一些人为的不正确的设置和配置,造成无法显示。 如果想解析出SYN报文,首先在Trace窗口选择正确的…

5个高清视频素材网站,免费下载~

免费高清视频素材网站,这几个你一定要知道,建议收藏! 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材非常丰富,网站主要还是以设计类素材为主,高清视频素材也很多,像风景、…

dcdc降压电路原理及仿真

在之前的文章 DCDC 降压芯片基本原理及选型主要参数介绍 中已经大致讲解了dcdc降压电路的工作原理,今天再结合仿真将buck电路工作过程讲一讲。 基本拓扑 上图为buck电路的基本拓扑结构,开关打到1,电感充电;开关打到0,…

pdf怎么转换成jpg格式的图片,5种方法详细教程

pdf怎么转换成jpg格式的图片,为什么这样做呢?那是因为将PDF转换成JPG格式的主要原因是方便在演示文稿、网页或社交媒体等平台上展示和分享PDF文件的内容。JPG格式具有广泛的兼容性和易于传输的特点,而且可以轻松地进行编辑和调整大小。此外&a…

Java反射简单介绍_01

文章目录 1. 什么是反射2. Java中类加载的三个阶段3. 反射机制提供的相关类4. Java中获取Class类的三种方式5. Class类提供的功能5.1. 获取Field类方法5.2. 获取Method类方法5.3. 获取Constructor类方法5.4. Class中其他方法 1. 什么是反射 Java中的反射主要是体现在运行期间,…

uniapp 用css画五边形(app 小程序)

效果图 css .scoreLabel{ background: $yxs-theme-color; width: 64rpx; height: 69rpx; line-height: 32rpx; font-size: 28rpx; font-family: DINPro; f…

点亮未来明灯,引领绿色革命

随着全球气候变化日趋严重,能源转型成为解决气候问题和提高全球能源安全合理性的必要措施之一。可持续能源技术因其对环境的友好性和可再生性而成为了当前热点话题。可持续能源技术已经成为人们日益关注的焦点。这项技术可以帮助我们减少对化石燃料的依赖&#xff0…

如何选择适合自己的小程序开发框架

随着微信、支付宝等开放平台的壮大,移动应用生态市场的蓬勃发展,例如小程序已经成为各个企业和开发者的重要选择。为了提高小程序的开发效率和代码重用性,许多第三方开发框架应运而生。 准备为需要的朋友整理一些常见的小程序第三方开发框架…

能伸展脖子的机器人?东京大学最新研究成果:基于鸵鸟肌肉骨骼结构和行为,具有高度灵活性的新型机械臂—RobOstrich(附论文)

原创 | 文 BFT机器人 得益于高度灵活的颈部,鸟类可以做很多事情,无论是转过头梳理自己的后背,在飞行过程中“眼观六路”,还是在地面或树上难以触及的角落和缝隙寻找食物。而在所有鸟类中,鸵鸟以其结实灵巧的颈部脱颖而…

顶部菜单栏-popuwindows

效果 布局文件 猜想与步骤 1.通过.9.png 制作尖尖效果, 2.popuwindows弹出布局框 以及灰色背景 3.点击按钮进入不同功能

QT运行程序后出现无法打开输出文件问题

:-1: error: cannot open output file release\Dailin.exe: Permission denied collect2.exe:-1: error: error: ld returned 1 exit status 如上所示报错。这个是因为用户写的程序开辟空间后没有释放造成的。用户需要把开辟了空间释放就可以了。 我的例子如下。 My_Uart *Ua…

【聚焦】“饶派杯”XCTF车联网安全挑战赛即将开启!

为深入贯彻落实国家网络强国和交通强国战略部署,推动智能网联汽车技术与产业发展、加快该领域人才培养、提升行业创新,打造自主可控、自主研发的中国智能网联汽车安全生态体系,由江西省委网信办、江西省工信厅、上饶市人民政府主办&#xff0…

【云渲染案例】《长月烬明》特效出圈?国内9家视效公司联手打造国风新仙侠!丨瑞云渲染案例

仙侠剧是中国电视剧的一大特色,也是很多观众喜爱的类型。近年来,仙侠剧的制作水平越来越高,由鞠觉亮执导,罗云熙、白鹿领衔主演的《长月烬明》就是一部在今年四月份引起了轰动的虐恋仙侠剧,它以炫丽的特效、新颖的剧情…

目前流行的9大前端框架

1. React 2. Vue 3. Angular 、 4. Svelte 官网:https://svelte.dev 中文官网:https://www.sveltejs.cn Svelte 是一种全新的构建用户界面的方法。传统框架如 React 和 Vue 在浏览器中需要做大量的工作,而 Svelte 将这些工作放到构建应用程…

WLAN,AP等

无线网络部署方案: AC直连式组网 AC旁挂式组网 WLAN 是无线局域网(Vireless Local Area Network)的简称 也称之为 Wi-Fi 简单理解:无线就是网线的一个延长 AC:无线控制器--统一管理AP AP:散发无线…

nginx 服务器总结

一. 负载均衡的作用有哪些? 1、转发功能 按照一定的算法【权重、轮询】,将客户端请求转发到不同应用服务器上,减轻单个服务器压力,提高 系统并发量。 2、故障移除 通过心跳检测的方式,判断应用服务器当前是否可以正常…

原神个人服务器替换模型(3Dmigoto)教程

原神个人服务器替换模型(3Dmigoto)教程 本期教程教大家如何修改原神私服角色模型 首先下载3Dmigoto (3Dmigoto是开源的自己有兴趣想法的在GIT搜) 打开3Dmigoto文件内的d3dx.ini文件 找到target (我们需要找到有路径的这个选项) …