深度学习-------------------使用块的网络VGG

VGG

在这里插入图片描述



AlexNet比LeNet更深更大,以得到更好的精度
能不能更深和更大?该如何更深更大?
选项:
    更多的全连接层(太贵)
    更多的卷积层
    将卷积层组合成块

在这里插入图片描述




VGG块

VGG块:
      3×3卷积(填充1)(n层,m通道(即:输入和输出通道是一样的))
      2×2最大池化层(步幅2)

为什么用的是3×3而不是5×5?
    因为5×5计算量大,得浅一点点。在同样的计算和开销下用3×3比5×5的效果好。即:深但窄效果更好。

在这里插入图片描述



VGG架构

        多个VGG块后接全连接层。
        不同次数的重复块得到不同的架构VGG-16,VGG-19。

在这里插入图片描述




进度

在这里插入图片描述

在这里插入图片描述




总结

    ①VGG使用可重复使用的卷积块来构建深度卷积神经网络。
    ②不同的卷积块个数和超参数可以得到不同复杂度的变种。




使用块的网络(VGG)

VGG块

    使用了带有 3×3 卷积核填充为1(保持高度和宽度)的卷积层,和带有 2×2 池化窗口步幅为2(每个块后的分辨率减半)的最大池化层。在下面的代码中,我们定义了一个名为vgg_block的函数来实现一个VGG块。该函数有三个参数,分别对应于卷积层的数量num_convs、输入通道的数量in_channels 和输出通道的数量out_channels.

import torch
from torch import nn
from d2l import torch as d2l
 
 
def vgg_block(num_convs, in_channels, out_channels):
	# 创建了一个空列表 layers,用于按顺序存储将要构建的层的实例。
    layers = []
    # 循环构建卷积层和ReLU层
    for _ in range(num_convs):
    	# 将这个卷积层添加到 layers 列表中。
        layers.append(nn.Conv2d(in_channels, out_channels,
                                kernel_size=3, padding=1))
        # 添加一个ReLU激活层到 layers 列表中。
        layers.append(nn.ReLU())
        # 更新 in_channels 为 out_channels,以便下一个卷积层可以正确接收当前卷积层的输出作为输入。
        in_channels = out_channels
    # 添加最大池化层
    layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
    # 使用 nn.Sequential 将 layers 列表中的所有层打包成一个有序的容器。*layers 是解包列表,使其元素作为 nn.Sequential 的参数。
    return nn.Sequential(*layers)



VGG网络

与AlexNet、LeNet一样,VGG网络可以分为两部分:第一部分主要由卷积层池化层组成,第二部分全连接层组成。

在这里插入图片描述
    原始VGG网络有5个卷积块,其中前两个块各有一个卷积层后三个块各包含两个卷积层。 第一个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。由于该网络使用8个卷积层和3个全连接层,因此它通常被称为VGG-11

# 第一个参数为几层卷积,第二个参数为输出通道数
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))

每一块是进行高宽减半,224最后分成5块,为什么是5块呢?

在这里插入图片描述
是奇数,已经不能在分了。
在这里插入图片描述

实现VGG-11,可以通过在conv_arch上执行for循环来简单实现。

def vgg(conv_arch):
	# 初始化一个空列表,用于存储VGG网络中的卷积块
    conv_blks = []
    # 假设输入图像的通道数为1(例如,灰度图像)。对于彩色图像,这通常是3  
    in_channels = 1
    # 卷积层部分
    # 遍历conv_arch列表,其中每个元素是一个包含两个值的元组:(卷积层数, 输出通道数) 
    for (num_convs, out_channels) in conv_arch:
    	# 为每个卷积块调用vgg_block函数,并将结果添加到conv_blks列表中
        conv_blks.append(vgg_block(num_convs, in_channels, out_channels))
        # 更新输入通道数,为构建下一个卷积块做准备
        in_channels = out_channels
 	# 构建并返回整个网络模型
    return nn.Sequential(
    	# 解包conv_blks列表,将其中的所有卷积块按顺序添加到Sequential模型中
    	# 将卷积层输出的多维特征图展平成一维,以便输入到全连接层
        *conv_blks, nn.Flatten(),
        # 全连接层部分
        # 全连接层的输入特征数量就是特征图的通道数乘以高度再乘以宽度。即:out_channels * 7 * 7
        # Dropout层,用于防止过拟合,丢弃率为0.5  
        nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),
        # 第二个全连接层,输入和输出特征数均为4096  
        nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
        nn.Linear(4096, 10))
# 调用vgg函数构建网络模型,并将conv_arch作为参数传递 
net = vgg(conv_arch)



观察每层输出的形状

构建一个高度和宽度为224的单通道数据样本,以观察每个层输出的形状

X = torch.randn(size=(1, 1, 224, 224))
for blk in net:
    X = blk(X)
    print(blk.__class__.__name__,'output shape:\t',X.shape) # VGG使得高宽减半,通道数加倍

结果:

在这里插入图片描述


该部分总代码

import torch
from torch import nn
from d2l import torch as d2l

def vgg_block(num_convs,in_channels,out_channels): # 卷积层个数、输入通道数、输出通道数
    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) # *layers表示把列表里面的元素按顺序作为参数输入函数     

conv_arch = ((1,64),(1,128),(2,256),(2,512),(2,512)) # 第一个参数为几层卷积,第二个参数为输出通道数

def vgg(conv_arch):
    conv_blks = []
    in_channels = 1
    for (num_convs, out_channels) in conv_arch:
        conv_blks.append(vgg_block(num_convs,in_channels,out_channels))
        in_channels = out_channels

    return nn.Sequential(*conv_blks, nn.Flatten(),
                         nn.Linear(out_channels * 7 * 7, 4096),nn.ReLU(),
                         nn.Dropout(0.5), nn.Linear(4096,4096),nn.ReLU(),
                         nn.Dropout(0.5), nn.Linear(4096,10))

net = vgg(conv_arch)

# 观察每个层输出的形状
X = torch.randn(size=(1,1,224,224))
for blk in net:
    X = blk(X)
    print(blk.__class__.__name__,'output shape:\t', X.shape) # VGG使得高宽减半,通道数加倍



训练模型

由于VGG-11比AlexNet计算量更大,因此我们构建了一个通道数较少的网络,足够用于训练Fashion-MNIST数据集。

ratio = 4
# conv_arch是一个列表,其中包含多个元组(pair)元组pair中包含两个参数,现在对第二个参数整除ratio目的是减小模型的大小
# 所有输出通道除以4
small_conv_arch = [(pair[0], pair[1] // ratio) for pair in conv_arch]
# VGG接受一个卷积层的配置列表
net = vgg(small_conv_arch)
X = torch.randn(size=(1, 1, 224, 224))
for blk in net:
    X = blk(X)
    print(blk.__class__.__name__,'output shape:\t',X.shape)



lr, num_epochs, batch_size = 0.05, 10, 128
# resize=224参数表明将图像的大小调整为224x224像素
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
# 尝试获取GPU,如果可用则使用GPU进行训练,以提高训练速度。如果GPU不可用,则默认使用CPU。
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

结果:
在这里插入图片描述

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Se-VGG16是一种基于VGG16的网络结构,它在VGG16的基础上进行了改进。VGG16是一个经典的卷积神经网络模型,由13个卷积层和3个全连接层组成,深度为16。Se-VGG16在VGG16的基础上添加了SE模,这是一种注意力机制,用于增强模型的表示能力和泛化能力。 SE模通过学习特征通道之间的关系,自适应地调整每个通道的权重。它包含两个关键步骤:先进行全局平均池化,将特征图的每个通道压缩成一个标量;然后,使用两个全连接层,将这个标量压缩成一个介于0和1之间的权重。最后,将这个权重乘以原始的特征图,得到加权后的特征图。 Se-VGG16的网络结构与VGG16相似,都由多个卷积层和全连接层组成。不同之处在于Se-VGG16在每个卷积的最后一个卷积层后添加了一个SE模。这样,每个卷积都会自适应地调整特征通道的权重,以提高模型的表达能力。 总结起来,Se-VGG16是在VGG16基础上添加了SE模的改进版。这种改进能够提高模型的表达能力和泛化能力,进一步提升了模型的性能。 : VGGNet模型有A-E五种结构网络,深度分别为11,11,13,16,19。其中较为典型的网络结构主要有vgg16和vgg19,本篇文章主要讲VGG16,并分享VGG16的Pytorch实现。 : 首先介绍一下感受野的概念。在卷积神经网络中,决定某一层输出结果中一个元素所对应的输入层的区域大小,被称作感受野(receptive field)。通俗的解释是,输出feature map上的一个单元对应输入层上的区域大小。 VGG亮点。 : keras官方预训练模型vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值