[动手学习深度学习]25. 使用块的网络VGG

发布于:2025-03-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

AlexNet在LeNet的基础上增加了3个卷积层,但AlexNet作者对她们的卷积窗口、输出通道数和构造顺序均作了大量的调整,存在最大的问题是长的不规则
虽然AlexNet指明了深度卷积网络可以取得出色的结果,但并没有提供简单的规则以指导后来的研究者如何设计新的网络
后面几节主要介绍几种不同的深度网络设计思路

VGG块

VGG思想:先把网络层组成一个小块,再拿小块螺上去
这里就提出了VGG块(其实也是AlexNet的拓展)
在这里插入图片描述
AlexNet里面是有3个33的卷积层,而在VGG中,这一部分可以无限重复,通过超参数n设置,同样输出通道也可以通过参数m配置
后面又用回了LeNet的2
2的最大池化层的窗口

  • 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表示将layers列表里的元素按顺序作为参数输入函数
    

    还可以用更省事的方式,即用LazyConv2d,首次前向传播时根据输入的尺寸自动确定输出的尺寸,这样可以更加灵活地处理不同大小的输入。

    def vgg_block(num_convs, out_channels):
        layers = []
        for _ in range(num_convs):
            layers.append(nn.LazyConv2d(out_channels, kernel_size=3, padding=1))
            layers.append(nn.ReLU())
        layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
        return nn.Sequential(*layers)
    
    
  • VGG块里为什么用33的卷积而不是用55
    55因为计算量大,所以肯定要浅一点
    在测试中发现,在同样的开销条件下,堆更多的3
    3要比少一点的5*5效果要好

在这基础上就得到了VGG架构
在这里插入图片描述
可以看出VGG相对于AlexNet的改进就是,将AlexNet新加的那一部分抽出来作为VGG块(去掉了AlexNet前面两层不规则的层),而块不同的重复次数就得到了不同的架构

# VGG-11网络的架构
# 这有5个块(每一块后面都有一个maxpooling层,把宽高减半)
# 选5个块是因为 224 / (2^5) = 7,后面就除不动了,所以只能作5块 (224是之前用的数据的值)
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)) # 最后一层输出10类

# 观察每个层输出的形状
X = torch.randn(1, 1, 224, 224)
for blk in vgg_block(2, 1, 64):
    X = blk(X)
    print(blk.__class__.__name__, 'output shape:\t', X.shape) # 输出形状为 (1, 64, 112, 112)

经典设计思想:宽高(空间)减半、通道数(模式)翻倍

总结

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

发展进度

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到