发布时间:2023-02-11 22:00
LeNet在小批量样本的处理中表现尚可,但当样本过于复杂时处理起来结果不尽如人意。
AlexNet出现于2010年后,该模型对较大批量数据(特别是图片较多和所包含信息较多的情况下)的处理表现不错,该模型与LeNet具有很高的相似性,在LeNet自1998年问世后,受当时硬件设备发展和网络训练优化算法等方面的滞后,人们很难使用卷积神经网络进行深层次的训练,因此其曾经一度被机器学习的方法所超越(如SVM),直到AlexNet网络的出现。
第一:模型构造不同
AlexNet与LeNet(指较小的卷积神经网络)在构造上有不同,AlexNet网络包含8层,其中包括5层卷积和2层全连接隐藏层,以及1个全连接输出层,其中
第一卷积层使用的 Kernel为11*11, 后接3*3 步幅为2的 池化层;
第二卷积层使用的 Kernel为5*5,后接3*3 步幅为2的池化层;
第三卷积层使用的 Kernel为3*3,直接与第四层相连;
第四卷积层使用的 Kernel为3*3,直接与第五层相连;
第五卷积层使用的 Kernel为3*3,后接3*3 步幅为2的池化层;
接下来,卷积部分结束后,其后紧跟两个输出均为4096的全连接隐藏层,最后为1个全连接输出层。
其结构图如下图所示:
第二:激活函数的改变
传统的LeNet网络使用的是sigmoid激活函数,而AlexNet使用的是ReLU函数。
ReLU函数比sigmoid函数计算上更为简单(不用求幂运算),且ReLU函数在不同的参数初始化方法下可以让模型更容易训练。
第三:AlexNet使用丢弃法来控制全连接层的模型复杂程度
丢弃法是深度模型中常用来应对过拟合问题的方法之一,其具体操作核心就是随机的丢弃某些层中(一般是中间层)的某些神经元,以此来降低后一层在计算中对上一层(随机丢弃的层)的过度依赖,起到正则化的作用(所谓正则化是指:在学习中降低模型复杂度和不稳定程度,是为了避免过拟合),但要注意的是丢弃法只在训练模型时使用。下图为使用了丢弃法的由两层全连接层构成的二层网络的结构,该网络中隐藏层的神经元随机丢失。
第四:AlexNet中引入了图像增广
AlexNet中引入了图像增广,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。所谓的图像增广指的是:该技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模;其另一种解释是,随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力(样本数据的适应能力)。
导入包及配置GPU
import time
import torch
from torch import nn, optim
import torchvision
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import sys
import d2lzh_pytorch as d2l
#配置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(
nn.Conv2d(1, 96, 11, 4), # in_channels, out_channels, kernel_size, stride, padding
nn.ReLU(),
nn.MaxPool2d(3, 2), # kernel_size, stride
# 减小卷积窗口,使用填充为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), #丢弃法
nn.Linear(4096, 4096),
nn.ReLU(),
nn.Dropout(0.5), #丢弃法
# 输出层,所以用类别数为10
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()
print(net)
所构造的AlexNet网络结果如下:
读取数据
batch_size = 128 #样本数量
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
训练模型
lr, num_epochs = 0.001, 5
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
训练结果展示如下:
AlexNet在结果上要优于LeNet很多,特别是其在处理大规模数据方便的优势更是明显。
AlexNet的问世也开启了深度学习在计算机视觉领域的大规模应用。
一般我们可以将其看做浅层神经网络和深层神经网络的分界线。