1 背景
AlexNet 由多伦多大学的 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 在 2012 年的 ImageNet 图像分类竞赛中提出,并以杰出的成绩获得第一名。在此之前,尽管上一节介绍的 LeNet 已经取得了一定影响,但由于当时的计算能力有限和数据集较小,卷积神经网络并未广泛使用。ImageNet 数据集与 AlexNet 的出现改变了这一局面,开启了卷积神经网络的新纪元。
2 原理
为了提升计算能力,AlexNet 实际上设计了两个 GPU 并行计算的结构,如下图所示:
为了便于理解本质,书中忽略了 AlexNet 模型在双 GPU 上运行的特点,并将其结构与 LeNet 进行了对比:
从图中可以看出,AlexNet 在 LeNet 的基础上进行了几项改进:1. 输入数据规模更大,通道数、高度和宽度均有所增加。2. 增加了 3 个卷积层和一个汇聚层,网络更深。3. 卷积层的卷积核和全连接层的节点数量更多,卷积和汇聚窗口也进行了调整。总体来看,除了汇聚层外,每层参数都增加了。
除了图中可见的改进之外,还有一些未展示的改进:1. AlexNet 将激活函数从 sigmoid 更改为 ReLU,ReLU 的计算更简单,并且能有效避免梯度消失问题。2. AlexNet 通过暂退法控制全连接层的模型复杂度,而 LeNet 只使用了权重衰减。3. 为了进一步扩大数据量,AlexNet 在训练时增加了大量图像增强数据,如翻转、裁剪和变色等,这使得模型更加健壮,更大的样本量有效减少了过拟合。
需要注意的是,虽然书中提到 LeNet 和 AlexNet 都使用了权重衰减,但在 d2l.train_ch6() 函数中的 SGD 优化器中未指定衰减率,似乎没有进行权重衰减。
3 实现
3.1 模型定义
由于数据集仍采用之前的 Fashion-MNIST 数据集,在模型的输入层通道数从原来的 3 改为 1,且最后一层输出长度从原来的 1000 修改为 10。
import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
# 这里使用一个11*11的更大窗口来捕捉对象。
# 同时,步幅为4,以减少输出的高度和宽度。
# 另外,输出通道的数目远大于LeNet
nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 使用三个连续的卷积层和较小的卷积窗口。
# 除了最后的卷积层,输出通道的数量进一步增加。
# 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Flatten(),
# 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
nn.Linear(6400, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
# 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
nn.Linear(4096, 10))
下面展示了每一层输出的形状 (B, C, H, W):
X = torch.randn(1, 1, 224, 224)
for layer in net:
X=layer(X)
print(layer.__class__.__name__,'output shape:\t',X.shape)
3.2 模型训练
由于 Fashion-MNIST 数据集中的图像大小为 28*28,需要通过 resize 参数将其缩放为 224*224 的图像(只指定一个参数时为等比缩放)。
batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
lr, num_epochs = 0.01, 10
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
这次训练耗时较长,在我的电脑上使用 RTX3050 GPU 训练耗时达到 13 分多,而上一章的 LeNet 训练仅花费了一分钟左右。
参考文献
- [1]《动手学深度学习》, https://zh-v2.d2l.ai/
- [2]?Alex Krizhevsky, Ilya Sutskever, and Geoffrey E. Hinton. 2017. ImageNet classification with deep convolutional neural networks. Commun. ACM 60, 6 (June 2017), 84–90. https://doi.org/10.1145/3065386


雷达卡


京公网安备 11010802022788号







