该论文提出了一种基于深度卷积神经网络(CNN)的图像分类方法,并在ILSVRC-2010和ILSVRC-2012图像分类挑战赛中取得了新的记录。主要工作和贡献如下:
3. 模型并行(model parrallel): 使用了两个GTX 580 3GB显卡并行训练,实现了高效的GPU卷积操作,显著减少了训练时间。
总体而言,该论文通过构建当时最大的卷积神经网络并使用各种优化技巧,在ImageNet等大规模图像数据集上取得了新的state-of-the-art结果,对后续的计算机视觉研究产生了重大影响。
使用的是ImageNet数据集,将所有图像缩放到256x256大小,如果图像尺寸不是正方形,先按比例缩小,然后从中间裁剪出256x256大小的正方形区域。
注意:此处是直接使用的原始RGB图片,没有进行SIFT的特征提取,这也被看作端到端的训练模型,简化了训练以及推理的流程,这种端到端的思想深刻影响了深度学习模型的发展,目前大多数模型均是采用端到端的方法进行训练的。
同时论文使用两种方法进行数据增强,第一种是对每张图片进行裁取和翻转,经过处理每张图片会得到十张图片输入模型预测出结果。第二种是对图片的RGB三个颜色通道进行平移和调整,即进行RGB通道强度调整。
论文中的模型作者用了两块GPU进行训练,即使用了模型并行的方法,这种方法会给模型的工程实践带来困难,所以在之后随着显卡性能的提升已很少使用,但目前在NLP领域,LLM(large language model)的训练再次遇到了算力瓶颈,以GPT为代表的大模型再次使用模型并行的方法进行训练。
模型一共有八层,前五层是CNN层,紧接着跟着两个全连接层,最后是一个1000类的softmax分类层。第二层,第四层,第五层的CNN层后面均跟着Max pooling层和LRM层(local response normalization,作用是防止过拟合)。两层全连接层均使用了Dropout的方法防止过拟合。实际上这两层全连接层是参数最多的,构成了模型训练的瓶颈,也是可能造成过拟合的罪魁祸首,为了防止过拟合,这两层全连接层都使用了Dropout的方法。
LRM层现在基本已不再使用,其作用现在普遍认为也比较小,故本文不再做介绍,只需知道论文作者使用其本意是为了防止过拟合,提升模型泛化能力。
其结构图可以简化为在单块gpu上进行训练的。
图片来源:https://blog.csdn.net/guzhao9901/article/details/118552085?spm=1001.2014.3001.5506
原图输入256 × 256,实际上进行了随机裁剪,实际大小为227 × 227。
<span style="background:#fff88f">
①卷积层C1
C1的基本结构:卷积–>局部响应归一化(LRN)–>ReLU–>池化
<span style="background:#fff88f">
②卷积层C2
C2的基本结构:卷积–>局部响应归一化(LRN)–>ReLU–>池化
<span style="background:#fff88f">
③卷积层C3
C3的基本结构为:卷积–>ReLU
<span style="background:#fff88f">
④ 卷积层C4
C4的基本结构为:卷积–>ReLU
<span style="background:#fff88f">
⑤ 卷积层C5
C5的基本结构为:卷积–>ReLU–>池化
<span style="background:#fff88f">
⑥全连接层FC6
FC6的基本结构为:卷积(全连接实现)–>ReLU–>Dropout
<span style="background:#fff88f">
⑦全连接层FC7
FC7的基本结构为:全连接–>ReLU–>Dropout
<span style="background:#fff88f">
⑧ 全连接层FC8
FC8的基本结构为:全连接–>softmax
$$ ReLU(x)=max(0,x) $$
ReLU函数的导数:
$$ {\sigma(x)} = \frac{1}{1 + e^{-x}} $$
Sigmoid函数的导数:
$$ \frac{d\sigma(x)}{dx} = \sigma(x) * (1 - \sigma(x)) = \frac{e^{-x}}{(1 + e^{-x})^2} $$
一个sigmoid函数大致相当于两个ReLU函数
关于ReLU的具体分析可以见这篇文章:(暂未更新)
重叠池化(overlapping pooling)是一种改进传统的池化层的策略。传统的池化层通常由间隔一定距离的池化单元组成,每个单元对相邻的神经元输出进行汇总。相邻池化单元所覆盖的区域不重叠。而重叠池化则通过设置池化单元之间的间隔小于池化区域大小来实现重叠,例如使用间隔2像素的池化单元和区域大小为3x3的池化单元。文中提到,相比传统的非重叠池化,使用重叠池化可以将模型在ImageNet数据集上的top-1错误率降低0.4%,top-5错误率降低0.3%。因此,重叠池化是一种改进池化层设计的策略,能够提高模型性能。
dropout是一种有效的正则化方法,可以减少深度卷积神经网络中全连接层过拟合的问题。
注意:dropout是解决的全连接层过拟合的问题,所以论文中的两个全连接层使用了dropout,而CNN层没有使用dropout
dropout的主要思想是:在每次前向传播时,以一定概率(如0.5)将每个隐藏神经元的输出置为0,使得每个神经元在每次前向传播时都有一定的概率不参与计算。论文中认为,这样做的目的是打破全连接层中不同神经元之间的复杂共适应性,迫使每个神经元学习更强大的特征表示,对不同的随机子集都有效。在测试时,不进行dropout,而是将每个神经元的输出乘以一定比例(如0.5),近似于取所有可能dropout网络结果的几何平均。
现在普遍认为dropout相当于一个L2正则项,可以有效减少过拟合问题,同时让模型更强大。值得注意的是,dropout在训练时会增加迭代收敛次数,但可以大大提高模型的泛化能力。
1import time
2import torch
3from torch import nn, optim
4import torchvision
5device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
6
7class AlexNet(nn.Module):
8 def __init__(self):
9 super(AlexNet, self).__init__()
10 self.conv = nn.Sequential(
11 nn.Conv2d(1, 96, 11, 4), # in_channels, out_channels, kernel_size, stride, padding
12 nn.ReLU(),
13 nn.MaxPool2d(3, 2), # kernel_size, stride
14 # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
15 nn.Conv2d(96, 256, 5, 1, 2),
16 nn.ReLU(),
17 nn.MaxPool2d(3, 2),
18 # 连续3个卷积层,且使用更小的卷积窗口。除了最后的卷积层外,进一步增大了输出通道数。
19 # 前两个卷积层后不使用池化层来减小输入的高和宽
20 nn.Conv2d(256, 384, 3, 1, 1),
21 nn.ReLU(),
22 nn.Conv2d(384, 384, 3, 1, 1),
23 nn.ReLU(),
24 nn.Conv2d(384, 256, 3, 1, 1),
25 nn.ReLU(),
26 nn.MaxPool2d(3, 2)
27 )
28 # 这里全连接层的输出个数比LeNet中的大数倍。使用丢弃层来缓解过拟合
29 self.fc = nn.Sequential(
30 nn.Linear(256*5*5, 4096),
31 nn.ReLU(),
32 nn.Dropout(0.5),
33 nn.Linear(4096, 4096),
34 nn.ReLU(),
35 nn.Dropout(0.5),
36 # 输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
37 nn.Linear(4096, 10),
38 )
39
40 def forward(self, img):
41 feature = self.conv(img)
42 output = self.fc(feature.view(img.shape[0], -1))
43 return output