AlexNet在LeNet的基础上增加了3个卷积层,但AlexNet作者对她们的卷积窗口、输出通道数和构造顺序均作了大量的调整,存在最大的问题是长的不规则
虽然AlexNet指明了深度卷积网络可以取得出色的结果,但并没有提供简单的规则以指导后来的研究者如何设计新的网络
后面几节主要介绍几种不同的深度网络设计思路
VGG块
VGG思想:先把网络层组成一个小块,再拿小块螺上去
这里就提出了VGG块(其实也是AlexNet的拓展)
AlexNet里面是有3个33的卷积层,而在VGG中,这一部分可以无限重复,通过超参数n设置,同样输出通道也可以通过参数m配置
后面又用回了LeNet的22的最大池化层的窗口
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因为计算量大,所以肯定要浅一点
在测试中发现,在同样的开销条件下,堆更多的33要比少一点的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使用可重复使用的卷积块来构建深度卷积神经网络
- 不同卷积块个数和超参数可以得到不同复杂度的变种