现代卷积神经网络 - 深度卷积神经网络(AlexNet)

深度卷积神经网络(AlexNet)

在LeNet提出后,卷积神经网络在计算机视觉和机器学习领域中很有名气。但卷积神经网络并没有主导这些领域。这是因为虽然LeNet在小数据上取得了很好的效果,但是在更大、更真实的数据集上训练卷积神经网络的性能和可行性还有待研究。事实上,在上世纪90年代初和2012年之间的大部分时间里,神经网络往往被其他机器学习方法超越,如支持向量机(support vector machincs)

在计算机视觉中,直接将神经网络与其他机器学习方法进行比较也许不公平。这是因为,卷积神经网络的输入是由原始像素值或是经过简单预处理(例如居中、缩放)的像素值组成。但在使用传统机器学习方法时,从业者永远不会将原始像素作为输入,在传统机器学习方法中,计算机视觉流水线经过人的手工精心设计的特征流水线组成。对于这些传统方法,大部分的进展都来自于对特征有了更聪明的想法,并且学习到的算法往往归于事后的解释

在上世纪90年代就有了一些神经网络加速卡,但仅靠它们还不足以开发出有大量参数的深层多通道多卷积神经网络。此外,当时的数据集仍然相对较小,除了这些障碍,训练神经网络的一些关键技巧仍然缺失,包括启发式参数初始化、随机梯度下降的变体、非挤压激活函数和有效的正则化技术

因此,与训练端到端(从像素到分类结果)系统不同,经典机器学习的流水线看起来更像下面这样:

  1. 获取一个有趣的数据集。在早期,收集这些数据集需要昂贵的传感器(在当时最先进的图像也就100万像素)
  2. 根据光学、几何学、其他知识以及偶然发现,手工对特征数据集进行预处理
  3. 通过标准的特征提取算法,如SIFT(尺度不变特征变换)和SURF(加速鲁棒特征)或其他手动调整的流水线来输入数据
  4. 将提取的特征送入最喜欢的分类器中(例如线性模型或其他核方法),以训练分类器

1 - 学习表征

另一种预测这个领域发展的方法——观察图像特征的提取方法。在2012年前,图像特征都是机械地计算出来的。事实上,设计一套新的特征函数,改进结果,并撰写论文是盛极一时的潮流。SIFT、SURF、HOG(定向梯度直方图)核类似的特征提取方法占据了主导地位。

另⼀组研究⼈员,包括Yann LeCun、Geoff Hinton、Yoshua Bengio、Andrew Ng、Shun ichi Amari和JuergenSchmidhuber,想法则与众不同:他们认为特征本⾝应该被学习。此外,他们还认为,在合理地复杂性前提下,特征应该由多个共同学习的神经⽹络层组成,每个层都有可学习的参数。在机器视觉中,最底层可能检测边缘、颜⾊和纹理。事实上,Alex Krizhevsky、Ilya Sutskever和Geoff Hinton提出了⼀种新的卷积神经⽹络变体AlexNet。在2012年ImageNet挑战赛中取得了轰动⼀时的成绩。AlexNet以Alex Krizhevsky的名字命名,他是论⽂ [Krizhevsky et al., 2012]的第⼀作者

有趣的是,在⽹络的最底层,模型学习到了⼀些类似于传统滤波器的特征抽取器。图7.1.1是从AlexNet论⽂[Krizhevsky et al., 2012]复制的,描述了底层图像特征

缺少的成分:数据

包含许多特征的深度模型需要大量的有标签数据,才能显著优于凸优化的传统方法(如线性方法和核方法),然而,限于早期计算机有限的存储和90年代有限的研究预算,大部分研究只基于小的公开数据集。例如,不少研究论文基于加州大学欧文分校(UCI)提供的若干个公开数据集,其中许多数据集只有几百至几千张在非自然环境下以低分辨率拍摄的图像。这一状况在2010年前后兴起的大数据浪潮中得到改善。2009年,ImagcNet数据集发布,并发起ImageNet挑战赛:要求研究人员从100万个样本中训练模型,以区分1000个不同类别的对象。ImageNet数据集由斯坦福教授李飞飞小组的研究人员开发,利用谷歌图像搜索(Google Image Search)对每一类图像进行筛选,并利用亚马逊众包(Amazon Mechanical Turk)来标注每张图片的相关类别。这种规模是前所未有的,这项被称为ImageNet的挑战赛推动了计算机视觉和机器学习研究的发展,挑战研究人员确定哪些模型能够在更大的数据规模下表现最好

缺少的成分:硬件

深度学习对计算资源要求很高,训练可能需要数百个迭代轮数,每次迭代都需要代价高昂的许多线性代数层传递数据。这也是为什么在20世纪90年代至21世纪处,优化凸目标的简单算法事研究人员的首选。然而,用GPU训练神经网络改变了这一格局。图形处理器(Graphics Processing Unit,GPU)早年用来加速图形处理,使电脑游戏玩家受益。GPU可优化高吞吐量的4 * 4矩阵和向量乘法,从而服务于基本的图形任务。幸运的是,这些数学运算与卷积层的计算惊人地相似。由此,英伟达(NVIDIA)和ATI已经开始为通用计算操作优化gpu,甚至把它们作为通用GPU(general-purpose GPUs,GPGPU)来销售

那么GPU比CPU强在哪里呢?

⾸先,我们深度理解⼀下中央处理器(Central Processing Unit,CPU)的核⼼。CPU的每个核⼼都拥有⾼时钟频率的运⾏能⼒,和⾼达数MB的三级缓存(L3Cache)。它们⾮常适合执⾏各种指令,具有分⽀预测器、深层流⽔线和其他使CPU能够运⾏各种程序的功能。然⽽,这种明显的优势也是它的致命弱点:通⽤核⼼的制造成本⾮常⾼。它们需要⼤量的芯⽚⾯积、复杂的⽀持结构(内存接⼝、内核之间的缓存逻辑、⾼速互连等等),⽽且它们在任何单个任务上的性能都相对较差。现代笔记本电脑最多有4核,即使是⾼端服务器也很少超过64核,因为它们的性价⽐不⾼

相⽐于CPU,GPU由100 ∼ 1000个⼩的处理单元组成(NVIDIA、ATI、ARM和其他芯⽚供应商之间的细节稍有不同),通常被分成更⼤的组(NVIDIA称之为warps)。虽然每个GPU核⼼都相对较弱,有时甚⾄以低于1GHz的时钟频率运⾏,但庞⼤的核⼼数量使GPU⽐CPU快⼏个数量级。例如,NVIDIA最近⼀代的Ampere GPU架构为每个芯⽚提供了⾼达312 TFlops的浮点性能,⽽CPU的浮点性能到⽬前为⽌还没有超过1 TFlops。之所以有如此⼤的差距,原因其实很简单:⾸先,功耗往往会随时钟频率呈⼆次⽅增⻓。对于⼀个CPU核⼼,假设它的运⾏速度⽐GPU快4倍,你可以使⽤16个GPU内核取代,那么GPU的综合性能就是CPU的16 × 1/4 = 4倍。其次,GPU内核要简单得多,这使得它们更节能。此外,深度学习中的许多操作需要相对较⾼的内存带宽,⽽GPU拥有10倍于CPU的带宽

回到2012年的重大突破,当Alex Krizhevsky和Ilya Sutskever实现了可以在GPU硬件上运⾏的深度卷积神经⽹络时,⼀个重⼤突破出现了。他们意识到卷积神经⽹络中的计算瓶颈:卷积和矩阵乘法,都是可以在硬件上并⾏化的操作。于是,他们使⽤两个显存为3GB的NVIDIA GTX580 GPU实现了快速卷积运算。他们的创新cuda-convnet90⼏年来它⼀直是⾏业标准,并推动了深度学习热潮

2 - AlexNet

2012年,AlextNet横空出世,它首次证明了学习到的特征可以超越手工设计的特征。它一举打破了计算机视觉研究的现状。AlexNet使用了8层卷积神经网络,并以很大的优势赢得了2012年ImageNet图形识别挑战赛。

AlexNet和LeNet的架构非常相似,如图7.1.2所示。注意,这里我们提供了一个稍微精简版本的AlexNet,去除了当年需要两个小型GPU同时运算的设计特点

模型设计

激活函数

此外,AlexNet将sigmoid激活函数改为更简单的ReLU激活函数。⼀⽅⾯,ReLU激活函数的计算更简单,它不需要如sigmoid激活函数那般复杂的求幂运算。另⼀⽅⾯,当使⽤不同的参数初始化⽅法时,ReLU激活函数使训练模型更加容易。当sigmoid激活函数的输出⾮常接近于0或1时,这些区域的梯度⼏乎为0,因此反向传播⽆法继续更新⼀些模型参数。相反,ReLU激活函数在正区间的梯度总是1。因此,如果模型参数没有正确初始化,sigmoid函数可能在正区间内得到⼏乎为0的梯度,从⽽使模型⽆法得到有效的训练

容量控制和预处理

AlexNet通过暂退法(4.6节)控制全连接层的模型复杂度,⽽LeNet只使⽤了权重衰减。为了进⼀步扩充数据,AlexNet在训练时增加了⼤量的图像增强数据,如翻转、裁切和变⾊。这使得模型更健壮,更⼤的样本量有效地减少了过拟合。我们将在 13.1节中更详细地讨论数据扩增

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)
)

我们构造一个高度和宽度都为224的单通道数据,来观察每一层输出的形状。它与图7.1.2中的AlexNet架构相匹配

X = torch.rand(1,1,224,224)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)
Conv2d output shape:	 torch.Size([1, 96, 54, 54])
ReLU output shape:	 torch.Size([1, 96, 54, 54])
MaxPool2d output shape:	 torch.Size([1, 96, 26, 26])
Conv2d output shape:	 torch.Size([1, 256, 26, 26])
ReLU output shape:	 torch.Size([1, 256, 26, 26])
MaxPool2d output shape:	 torch.Size([1, 256, 12, 12])
Conv2d output shape:	 torch.Size([1, 384, 12, 12])
ReLU output shape:	 torch.Size([1, 384, 12, 12])
Conv2d output shape:	 torch.Size([1, 384, 12, 12])
ReLU output shape:	 torch.Size([1, 384, 12, 12])
Conv2d output shape:	 torch.Size([1, 256, 12, 12])
ReLU output shape:	 torch.Size([1, 256, 12, 12])
MaxPool2d output shape:	 torch.Size([1, 256, 5, 5])
Flatten output shape:	 torch.Size([1, 6400])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 10])

3 - 读取数据集

尽管文本中AlexNet是在ImageNet上训练的,但我们在这里使用的是Fashion-MNIST数据集。因为即使在现代GPU上,训练ImageNet模型,同时使其收敛可能需要数⼩时或数天的时间。将AlexNet直接应⽤于FashionMNIST的⼀个问题是,Fashion-MNIST图像的分辨率(28×28像素)低于ImageNet图像。为了解决这问题,我们将它们增加到224×224(通常来讲这不是⼀个明智的做法,但我们在这⾥这样做是为了有效使⽤AlexNet架构)。我们使⽤d2l.load_data_fashion_mnist函数中的resize参数执⾏此调整

batch_size = 128
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size,resize=224)

4 - 训练AlexNet

现在,我们已经开始训练AlexNet了,与LeNet相比,这里的主要变化是使用更小的学习速率训练,这是因为网络更深更广、图像分辨率更高,训练卷积神经网络就更昂贵

lr,num_epochs = 0.01,10
d2l.train_ch6(net,train_iter,test_iter,num_epochs,lr,d2l.try_gpu())
loss 0.334, train acc 0.879, test acc 0.878
1577.2 examples/sec on cuda:0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cHbDOjH-1663510681979)(https://yingziimage.oss-cn-beijing.aliyuncs.com/img/202209182213383.svg)]

5 - 小结

  • AlexNet的架构与LeNet相似,但使用了更多的卷积层和更多的参数来拟合大规模的ImageNet数据集
  • 今天,AlexNet已经被更有效的架构所超越,但它是从浅层网络到深层网络的关键一步
  • 尽管AlexNet的代码只比LeNet多出几行,但学术界花了很多年才接受深度学习这一概念,并应用其出色的实验结果。这也是由于缺乏有效的计算工具
  • Dropout、ReLU和预处理是提升计算机视觉任务性能的其他关键步骤
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值