动手学深度学习(PyTorch实现)(八)--AlexNet模型

Winema ·
更新时间:2024-09-20
· 888 次阅读

AlexNet模型1. AlexNet模型介绍1.1 AlexNet的特点1.2 AlexNet的结构1.3 AlexNet参数数量2. AlexNet的PyTorch实现2.1 导入相应的包2.2 构建AlexNet网络2.3 加载数据集2.4 训练网络 1. AlexNet模型介绍

由于受到计算机性能的影响,虽然LeNet在图像分类中取得了较好的成绩,但是并没有引起很多的关注。 直到2012年,Alex等人提出的AlexNet网络在ImageNet大赛上以远超第二名的成绩夺冠,卷积神经网络乃至深度学习重新引起了广泛的关注。AlexNet首次证明了学习到的特征可以超越⼿⼯设计的特征,从而⼀举打破计算机视觉研究的前状

1.1 AlexNet的特点

AlexNet是在LeNet的基础上加深了网络的结构,学习更丰富更高维的图像特征。AlexNet的特点:

更深的网络结构 使用层叠的卷积层,即卷积层+卷积层+池化层来提取图像的特征 使用Dropout抑制过拟合 使用数据增强Data Augmentation抑制过拟合 使用Relu替换之前的sigmoid的作为激活函数 多GPU训练 1.2 AlexNet的结构

AlexNet的结构为:
在这里插入图片描述
上图是论文中的原图,比较复杂,不容易看清楚,下图是更清晰的结构图:
Image Name
网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布。

卷积层C1 该层的处理流程是: 卷积–>ReLU–>池化–>归一化。 卷积,输入是227×227,使用96个11×11×3的卷积核,得到的FeatureMap为55×55×96。 ReLU,将卷积层输出的FeatureMap输入到ReLU函数中。 池化,使用3×3步长为2的池化单元(重叠池化,步长小于池化单元的宽度),输出为27×27×96((55−3)/2+1=27) 局部响应归一化,使用k=2,n=5,α=10−4,β=0.75进行局部归一化,输出的仍然为27×27×96,输出分为两组,每组的大小为27×27×48 卷积层C2 该层的处理流程是:卷积–>ReLU–>池化–>归一化 卷积,输入是2组27×27×48。使用2组,每组128个尺寸为5×5×48的卷积核,并作了边缘填充padding=2,卷积的步长为1. 则输出的FeatureMap为2组,每组的大小为27×27 times128. ((27+2∗2−5)/1+1=27) ReLU,将卷积层输出的FeatureMap输入到ReLU函数中 池化运算的尺寸为3×3,步长为2,池化后图像的尺寸为(27−3)/2+1=13,输出为13×13×256 局部响应归一化,使用k=2,n=5,α=10−4,β=0.75进行局部归一化,输出的仍然为13×13×256,输出分为2组,每组的大小为13×13×128 卷积层C3 该层的处理流程是: 卷积–>ReLU 卷积,输入是13×13×256,使用2组共384尺寸为3×3×256的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13 times384 ReLU,将卷积层输出的FeatureMap输入到ReLU函数中 卷积层C4 该层的处理流程是: 卷积–>ReLU 该层和C3类似。 卷积,输入是13×13×384,分为两组,每组为13×13×192.使用2组,每组192个尺寸为3×3×192的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13 times384,分为两组,每组为13×13×192 ReLU,将卷积层输出的FeatureMap输入到ReLU函数中 卷积层C5 该层处理流程为:卷积–>ReLU–>池化 卷积,输入为13×13×384,分为两组,每组为13×13×192。使用2组,每组为128尺寸为3×3×192的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13×256 ReLU,将卷积层输出的FeatureMap输入到ReLU函数中 池化,池化运算的尺寸为3×3,步长为2,池化后图像的尺寸为 (13−3)/2+1=6,即池化后的输出为6×6×256 全连接层FC6 该层的流程为:(卷积)全连接 -->ReLU -->Dropout 卷积->全连接: 输入为6×6×256,该层有4096个卷积核,每个卷积核的大小为6×6×256。由于卷积核的尺寸刚好与待处理特征图(输入)的尺寸相同,即卷积核中的每个系数只与特征图(输入)尺寸的一个像素值相乘,一一对应,因此,该层被称为全连接层。由于卷积核与特征图的尺寸相同,卷积运算后只有一个值,因此,卷积后的像素层尺寸为4096×1×1,即有4096个神经元。 ReLU,这4096个运算结果通过ReLU激活函数生成4096个值 Dropout,抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元 全连接层FC7 流程为:全连接–>ReLU–>Dropout 全连接,输入为4096的向量 ReLU,这4096个运算结果通过ReLU激活函数生成4096个值 Dropout,抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元 输出层 第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出1000个float型的值,这就是预测 1.3 AlexNet参数数量

卷积层的参数 = 卷积核的数量 * 卷积核 + 偏置

C1: 96个11×11×3的卷积核,96×11×11×3+96=34848 C2: 2组,每组128个5×5×48的卷积核,(128×5×5×48+128)×2=307456 C3: 384个3×3×256的卷积核,3×3×256×384+384=885120 C4: 2组,每组192个3×3×192的卷积核,(3×3×192×192+192)×2=663936 C5: 2组,每组128个3×3×192的卷积核,(3×3×192×128+128)×2=442624 FC6: 4096个6×6×256的卷积核,6×6×256×4096+4096=37752832 FC7: 4096∗4096+4096=16781312 output: 4096∗1000=4096000
卷积层 C2,C4,C5中的卷积核只和位于同一GPU的上一层的FeatureMap相连。从上面可以看出,参数大多数集中在全连接层,在卷积层由于权值共享,权值参数较少。 2. AlexNet的PyTorch实现 2.1 导入相应的包 import time import torch from torch import nn, optim import torchvision import numpy as np import sys sys.path.append("/home/kesci/input/") import d2lzh1981 as d2l import os import torch.nn.functional as F 2.2 构建AlexNet网络 # 如果有GPU,开启GPU device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') class AlexNet(nn.Module): def __init__(self): super(AlexNet, self).__init__() self.conv = nn.Sequential( # in_channels, out_channels, kernel_size, stride, padding nn.Conv2d(1, 96, 11, 4), nn.ReLU(), # kernel_size, stride nn.MaxPool2d(3, 2), # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数 nn.Conv2d(96, 256, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(3, 2), # 连续3个卷积层,且使用更小的卷积窗口。除了最后的卷积层外,进一步增大了输出通道数。 # 前两个卷积层后不使用池化层来减小输入的高和宽 nn.Conv2d(256, 384, 3, 1, 1), nn.ReLU(), nn.Conv2d(384, 384, 3, 1, 1), nn.ReLU(), nn.Conv2d(384, 256, 3, 1, 1), nn.ReLU(), nn.MaxPool2d(3, 2) ) # 这里全连接层的输出个数比LeNet中的大数倍。使用丢弃层来缓解过拟合 self.fc = nn.Sequential( nn.Linear(256*5*5, 4096), nn.ReLU(), nn.Dropout(0.5), #由于使用CPU镜像,精简网络,若为GPU镜像可添加该层 #nn.Linear(4096, 4096), #nn.ReLU(), #nn.Dropout(0.5), # 输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000 nn.Linear(4096, 10), ) def forward(self, img): feature = self.conv(img) output = self.fc(feature.view(img.shape[0], -1)) return output # 新建AlexNet网络 net = AlexNet() 2.3 加载数据集 # 加载Fashion MNIST数据集 def load_data_fashion_mnist(batch_size, resize=None, root='/home/kesci/input/FashionMNIST2065'): """Download the fashion mnist dataset and then load into memory.""" trans = [] if resize: trans.append(torchvision.transforms.Resize(size=resize)) trans.append(torchvision.transforms.ToTensor()) transform = torchvision.transforms.Compose(trans) mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=True, transform=transform) mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=True, transform=transform) train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=2) test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=2) return train_iter, test_iter batch_size = 16 # 如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = load_data_fashion_mnist(batch_size,224) 2.4 训练网络 lr, num_epochs = 0.001, 3 optimizer = torch.optim.Adam(net.parameters(), lr=lr) # .train_ch5()函数在LeNet模型中已经定义,不在重复定义 d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
作者:爱吃骨头的猫、



动手学 pytorch 学习 alexnet 深度学习

需要 登录 后方可回复, 如果你还没有账号请 注册新账号