AlexNet是由Alex Krizhevsky、Ilya Sutskever(均为Hinton的学生)和Geoffrey Hinton(被誉为”人工智能教父“,首先将反向传播用于多层神经网络)在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在 ImageNet 大规模视觉识别竞赛中取得了优异的成绩,把深度学习模型在比赛中的正确率提升到一个前所未有的高度,它的出现对深度学习发展具有里程碑式的意义。论文在写作过程中并没有提及将本网络架构称为AlexNet,而是后来人们将一作作者的名字融入,称为AlexNet。
论文原文:ImageNet Classification with Deep Convolutional Neural Networks
本文将首先介绍 AlexNet 的基本结构,然后讲述AlexNet的创新点,最后给出了基于pytorch的AlexNet代码实现。
一、AlexNet基本结构
AlexNet输入为RGB三通道的224 × 224 × 3大小的图像,共包含5 个卷积层和 3 个全连接层。其中,每个卷积层都包含卷积核、偏置项、ReLU激活函数。而第1、2、5个卷积层后面都跟着一个最大池化层(Max Pooling Layer),第1、2个卷积层后跟着局部响应归一化(LRN)模块,后面三个层为全连接层,最终输出层为softmax,将网络输出转化为概率值,用于预测图像的类别。
下图是AlexNet的网络结构图,从中可以看到网络结构在部署的时候采用的是双GPU方式,但是随着并行计算等算法的出现,这种方式也变得麻烦且不高效,一般不会采用。
各层网络参数设置
输入尺寸 | 卷积/池化核尺寸 | 步长stride | 填充padding | 输出尺寸 | |
卷积层C1(ReLU) | 224 × 224 × 3 | 11×11×3(96个) | 4 | 0 | 55×55×48(一对) |
最大池化层 | 55×55×48(一对) | 3×3 | 2 | 0 | 27×27×48(一对) |
LRN | |||||
卷积层C2(ReLU) | 27×27×48(一对) | 5× 5×48(256个) | 1 | 2 | 27×27×128(一对) |
最大池化层 | 27×27×128(一对) | 3×3 | 2 | 0 | 13×13×128(一对) |
LRN | |||||
卷积层C3(ReLU) | 13×13×128(一对) | 3×3×256(384个) | 1 | 1 | 13×13×192(一对) |
卷积层C4(ReLU) | 13×13×192(一对) | 3×3x192(384个) | 1 | 1 | 13×13×192(一对) |
卷积层C5(ReLU) | 13×13×192(一对) | 3×3 ×192(256个) | 1 | 1 | 13×13×128(一对) |
最大池化层 | 13×13×128(一对) | 3×3 | 2 | 0 | 6×6×128(一对) |
全连接层FC6(ReLU) | 6×6×128(一对) | 6×6×256(4096个) | 1 | 0 | 1×1×4096 |
全连接层FC7 (ReLU) | 1×1×4096 | / | / | / | 1×1×4096 |
全连接层FC8(softmax) | 1×1×4096 | / | / | / | 1×1×1000 |
二、 创新点
1、更深的神经网络结构
AlexNet 是首个真正意义上的深度卷积神经网络,它的深度达到了当时先前神经网络的数倍。通过增加网络深度,AlexNet 能够更好地学习数据集的特征,从而提高了图像分类的精度。
2. 使用ReLU作为激活函数
ReLU(Rectified Linear Unit)是一种非线性激活函数,尽管它的表达式看起来简单:f(x)=max(0,x) ,可能会认为正值部分是线性的,因此 ReLU 整体上也是线性的。然而,它实际上是非线性的,这是因为它改变了输入输出之间的关系。首先是,分段定义导致非线性。ReLU 的定义分为两部分:
虽然 y=x 是线性的,但当 y=0 和 y=x 拼接在一起时,整个函数变得非线性,因为它在 x=0 的位置发生了“转折”(即斜率不再连续)。其次是,破坏线性叠加性。如果一个神经网络中所有的操作(权重乘积、加法)都是线性的,那么无论堆叠多少层,最终的输出仍然是输入的线性变换。这会导致网络无法拟合复杂的非线性数据。ReLU 通过其分段特性(在某些输入上输出为 0)破坏了线性叠加性:
这使得网络能够通过组合多个 ReLU 激活函数来表示复杂的非线性函数。最后是,梯度的非线性行为。ReLU 的导数(梯度)如下:
这种分段的梯度行为在反向传播时也是非线性的,在某些区域梯度为 0,这意味着这些区域的权重不会被更新;在其他区域梯度为 1,权重会正常更新。这种选择性更新(由梯度的非线性决定)进一步增强了网络的非线性建模能力。
知道了为什么ReLU函数也是一种非线性激活函数之后,我们看一下ReLU函数的优点。相比于传统的sigmoid和 tanh 函数,ReLU 能够在保持计算速度的同时,有效地解决了梯度消失问题,从而使得训练更加高效。观察sigmoid和 tanh 函数,我们可以看到,当x变得很大或很小时,梯度几乎为0,也就出现了梯度消失的现象,当梯度消失发生时,最后一个隐层梯度更新基本正常,但是越往前的隐层内更新越慢,甚至有可能会出现停滞,此时,多层深度神经网络可能会退化为浅层的神经网络(只有后面几层在学习),因为浅层基本没有学习,对输入仅仅做了一个映射而已,从而导致了浅层网络的参数发生了变化微弱。
3. 局部响应归一化(LRN)的使用
LRN是在卷积层和池化层之间添加的一种归一化操作。在卷积层中,每个卷积核都对应一个特征图,LRN就是对这些特征图进行归一化。对于每个特征图上的每个位置,计算该位置周围的像素的平方和,然后将当前位置的像素值除以这个和。计算过程可以用以下公式表示:
LRN本质是抑制邻近神经元的响应(侧抑制),从而增强了神经元的较大响应。这种技术在一定程度上能够避免过拟合,并提高网络的泛化能力。现在通常不会被使用,有更多其他的归一化方式。
4、数据增强和Dropout(训练技巧)
为了防止过拟合,AlexNet 引入了数据增强和 Dropout 技术。数据增强可以通过对图像进行旋转、翻转、裁剪等变换,增加训练数据的多样性,提高模型的泛化能力。Dropout 则是在训练过程中随机删除一定比例的神经元,强制网络学习多个互不相同的子网络,从而提高网络的泛化能力。Dropout简单来说就是在前向传播的时候,让某个神经元的激活值以一定的概率p丢失,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征。
三、 代码
网络构建代码如下:(model.py)
import torch.nn as nn
import torch.utils.model_zoo as model_zoo__all__ = ['AlexNet', 'alexnet']model_urls = {'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth',
}class AlexNet(nn.Module):def __init__(self, num_classes=1000):super(AlexNet, self).__init__()self.features = nn.Sequential(nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(64, 192, kernel_size=5, padding=2),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(192, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.Conv2d(384, 256, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.Conv2d(256, 256, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),)self.classifier = nn.Sequential(nn.Dropout(),nn.Linear(256 * 6 * 6, 4096),nn.ReLU(inplace=True),nn.Dropout(),nn.Linear(4096, 4096),nn.ReLU(inplace=True),nn.Linear(4096, num_classes),)def forward(self, x):x = self.features(x)x = x.view(x.size(0), 256 * 6 * 6) #进行展平x = self.classifier(x)return xdef alexnet(pretrained=False, model_root=None, **kwargs):model = AlexNet(**kwargs)if pretrained:model.load_state_dict(model_zoo.load_url(model_urls['alexnet'], model_root))return model
参考资料:
卷积神经网络经典回顾之AlexNet - 知乎https://zhuanlan.zhihu.com/p/61854575724 深度卷积神经网络 AlexNet【动手学深度学习v2】_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1h54y1L7oe/?spm_id_from=333.337.search-card.all.click&vd_source=0dc0c2075537732f2b9a894b24578eedCV-baselinel-AlexNet-06-训练技巧_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV167411371Y/?spm_id_from=333.788.player.switch&vd_source=0dc0c2075537732f2b9a894b24578eed&p=6