二十八: 深度学习 (完结)

深度学习是加深了层的深度神经网络。基于之前介绍的网络,只需通过叠加层,就可以创建深度网络。

1. 加深网络

1.1 向更深的网络出发

我们来创建一个如图 8-1 所示的网络结构的 CNN(一个比之前的网络都深的网络)。这个网络的层比之前实现的网络都更深。这里使用的卷积层全都是 3 × 3 的小型滤波器,特点是随着层的加深,通道数变大(卷积层的通道数从前面的层开始按顺序以 16、16、32、32、64、64 的方式增加)。此外,如图 8-1 所示,插入了池化层,以逐渐减小中间数据的空间大小;并且,后面的全连接层中使用了 Dropout 层。


图 8-1 进行手写数字识别的深度 CNN

这个网络使用 He 初始值作为权重的初始值,使用 Adam 更新权重参数。把上述内容总结起来,这个网络有如下特点。

  • 基于 3×3 的小型滤波器的卷积层。
  • 激活函数是 ReLU。
  • 全连接层的后面使用 Dropout 层。
  • 基于 Adam 的最优化。
  • 使用 He 初始值作为权重初始值。

从这些特征中可以看出,图 8-1 的网络中使用了多个之前介绍的神经网络技术。现在,我们使用这个网络进行学习。先说一下结论,这个网络的识别精度为 99.38% 1 ,可以说是非常优秀的性能了!

实现图 8-1 的网络的源代码在 ch08/deep_convnet.py 中,训练用的代码在 ch08/train_deepnet.py 中。虽然使用这些代码可以重现这里进行的学习,不过深度网络的学习需要花费较多的时间(大概要半天以上)。

图 8-1 的网络的错误识别率只有 0.62%。这里我们实际看一下在什么样的图像上发生了识别错误。图 8-2 中显示了识别错误的例子。


图 8-2 识别错误的图像的例子:各个图像的左上角显示了正确解标签,右下角显示了本网络的推理结果

观察图 8-2 可知,这些图像对于我们人类而言也很难判断。这次的深度 CNN 尽管识别精度很高,但是对于某些图像,也犯了和人类同样的"识别错误"。

1.2 进一步提高识别精度

集成学习、学习率衰减、Data Augmentation (数据扩充)等都有助于提高识别精度。

尤其是 Data Augmentation,虽然方法很简单,但在提高识别精度上效果显著。

Data Augmentation 基于算法"人为地"扩充输入图像(训练图像)。具体地说,如图 8-4 所示,对于输入图像,通过施加旋转、垂直或水平方向上的移动等微小变化,增加图像的数量。这在数据集的图像数量有限时尤其有效。


图 8-4 Data Augmentation 的例子

除了如图 8-4 所示的变形之外,Data Augmentation 还可以通过其他各种方法扩充图像,比如裁剪图像的"crop 处理"、将图像左右翻转的"flip 处理"(flip 处理只在不需要考虑图像对称性的情况下有效) 等。对于一般的图像,施加亮度等外观上的变化、放大缩小等尺度上的变化也是有效的。不管怎样,通过 Data Augmentation 巧妙地增加训练图像,就可以提高深度学习的识别精度。虽然这个看上去只是一个简单的技巧,不过经常会有很好的效果。

1.3 加深层的动机

首先,从以 ILSVRC 为代表的大规模图像识别的比赛结果中可以看出加深层的重要性。这种比赛的结果显示,最近前几名的方法多是基于深度学习的,并且有逐渐加深网络的层的趋势。也就是说,可以看到层越深,识别性能也越高。

加深层的其中一个好处就是可以减少网络的参数数量。与没有加深层的网络相比,加深了层的网络可以用更少的参数达到同等水平(或者更强)的表现力。这一点结合卷积运算中的滤波器大小来思考就好理解了。比如,图 8-5 展示了由 5 × 5 的滤波器构成的卷积层。


图 8-5 5×5 的卷积运算的例子

这里希望大家考虑一下输出数据的各个节点是从输入数据的哪个区域计算出来的。显然,在图 8-5 的例子中,每个输出节点都是从输入数据的某个 5 × 5 的区域算出来的。接下来我们思考一下图 8-6 中重复两次 3 × 3 的卷积运算的情形。此时,每个输出节点将由中间数据的某个 3 × 3 的区域计算出来。那么,中间数据的 3 × 3 的区域又是由前一个输入数据的哪个区域计算出来的呢?仔细观察图 8-6,可知它对应一个 5 × 5 的区域。也就是说,图 8-6 的输出数据是"观察"了输入数据的某个 5 × 5 的区域后计算出来的。


图 8-6 重复两次 3×3 的卷积层的例子

一次 5 × 5 的卷积运算的区域可以由两次 3 × 3 的卷积运算抵充。并且,相对于前者的参数数量 25(5 × 5),后者一共是 18(2 × 3 × 3),通过叠加卷积层,参数数量减少了。而且,这个参数数量之差会随着层的加深而变大。比如,重复三次 3 × 3 的卷积运算时,参数的数量总共是 27。而为了用一次卷积运算"观察"与之相同的区域,需要一个 7 × 7 的滤波器,此时的参数数量是 49。

叠加小型滤波器来加深网络的好处是可以减少参数的数量,扩大感受野 (receptive field,给神经元施加变化的某个局部空间区域)。并且,通过叠加层,将 ReLU 等激活函数夹在卷积层的中间,进一步提高了网络的表现力。这是因为向网络添加了基于激活函数的"非线性"表现力,通过非线性函数的叠加,可以表现更加复杂的东西。

加深层的另一个好处就是使学习更加高效。与没有加深层的网络相比,通过加深层,可以减少学习数据,从而高效地进行学习。CNN 的卷积层会分层次地提取信息。具体地说,在前面的卷积层中,神经元会对边缘等简单的形状有响应,随着层的加深,开始对纹理、物体部件等更加复杂的东西有响应。

我们先牢记这个网络的分层结构,然后考虑一下"狗"的识别问题。要用浅层网络解决这个问题的话,卷积层需要一下子理解很多"狗"的特征。"狗"有各种各样的种类,根据拍摄环境的不同,外观变化也很大。因此,要理解"狗"的特征,需要大量富有差异性的学习数据,而这会导致学习需要花费很多时间。

不过,通过加深网络,就可以分层次地分解需要学习的问题。因此,各层需要学习的问题就变成了更简单的问题。比如,最开始的层只要专注于学习边缘就好,这样一来,只需用较少的学习数据就可以高效地进行学习。这是为什么呢?因为和印有"狗"的照片相比,包含边缘的图像数量众多,并且边缘的模式比"狗"的模式结构更简单。

通过加深层,可以分层次地传递信息,这一点也很重要。比如,因为提取了边缘的层的下一层能够使用边缘的信息,所以应该能够高效地学习更加高级的模式。也就是说,通过加深层,可以将各层要学习的问题分解成容易解决的简单问题,从而可以进行高效的学习。

以上就是对加深层的重要性的増补性说明。

2. 深度学习的小历史

一般认为,现在深度学习之所以受到大量关注,其契机是 2012 年举办的大规模图像识别大赛 ILSVRC(ImageNet Large Scale Visual Recognition Challenge)。在那年的比赛中,基于深度学习的方法(通称 AlexNet)以压倒性的优势胜出,彻底颠覆了以往的图像识别方法。2012 年深度学习的这场逆袭成为一个转折点,在之后的比赛中,深度学习一直活跃在舞台中央。

2.1 ImageNet

ImageNet 是拥有超过 100 万张图像的数据集。如图 8-7 所示,它包含了各种各样的图像,并且每张图像都被关联了标签(类别名)。每年都会举办使用这个巨大数据集的 ILSVRC 图像识别大赛。


图 8-7 大规模数据集 ImageNet 的数据例

ILSVRC 大赛有多个测试项目,其中之一是"类别分类"(classification),在该项目中,会进行 1000 个类别的分类,比试识别精度。我们来看一下最近几年的 ILSVRC 大赛的类别分类项目的结果。图 8-8 中展示了从 2010 年到 2015 年的优胜队伍的成绩。这里,将前 5 类中出现正确解的情况视为"正确",此时的错误识别率用柱形图来表示。

图 8-8 中需要注意的是,以 2012 年为界,之后基于深度学习的方法一直居于首位。实际上,我们发现 2012 年的 AlexNet 大幅降低了错误识别率。并且,此后基于深度学习的方法不断在提升识别精度。特别是 2015 年的 ResNet(一个超过 150 层的深度网络)将错误识别率降低到了 3.5%。据说这个结果甚至超过了普通人的识别能力。


图 8-8 ILSCRV 优胜队伍的成绩演变:竖轴是错误识别率,横轴是年份。横轴的括号内是队伍名或者方法名

2.2 VGG

VGG 是由卷积层和池化层构成的基础的 CNN。不过,如图 8-9 所示,它的特点在于将有权重的层(卷积层或者全连接层)叠加至 16 层(或者 19 层),具备了深度(根据层的深度,有时也称为"VGG16"或"VGG19")。

VGG 中需要注意的地方是,基于 3×3 的小型滤波器的卷积层的运算是连续进行的。如图 8-9 所示,重复进行"卷积层重叠 2 次到 4 次,再通过池化层将大小减半"的处理,最后经由全连接层输出结果。

VGG 结构简单,应用性强,所以很多技术人员都喜欢使用基于 VGG 的网络。

图 8-9 VGG

2.3 GoogLeNet

GoogLeNet 的网络结构如图 8-10 所示。图中的矩形表示卷积层、池化层等。


图 8-10 GoogLeNet

只看图的话,这似乎是一个看上去非常复杂的网络结构,但实际上它基本上和之前介绍的 CNN 结构相同。不过,GoogLeNet 的特征是,网络不仅在纵向上有深度,在横向上也有深度(广度)。

GoogLeNet 在横向上有"宽度",这称为"Inception 结构",以图 8-11 所示的结构为基础。


图 8-11 GoogLeNet 的 Inception 结构

如图 8-11 所示,Inception 结构使用了多个大小不同的滤波器(和池化),最后再合并它们的结果。GoogLeNet 的特征就是将这个 Inception 结构用作一个构件(构成元素)。此外,在 GoogLeNet 中,很多地方都使用了大小为 1 × 1 的滤波器的卷积层。这个 1 × 1 的卷积运算通过在通道方向上减小大小,有助于减少参数和实现高速化处理。

2.4 ResNet

ResNet 是微软团队开发的网络。它的特征在于具有比以前的网络更深的结构。

我们已经知道加深层对于提升性能很重要。但是,在深度学习中,过度加深层的话,很多情况下学习将不能顺利进行,导致最终性能不佳。ResNet 中,为了解决这类问题,导入了"快捷结构"(也称为"捷径"或"小路")。导入这个快捷结构后,就可以随着层的加深而不断提高性能了(当然,层的加深也是有限度的)。

如图 8-12 所示,快捷结构横跨(跳过)了输入数据的卷积层,将输入 x 合计到输出。

图 8-12 中,在连续 2 层的卷积层中,将输入 x 跳着连接至 2 层后的输出。这里的重点是,通过快捷结构,原来的 2 层卷积层的输出 F(x) 变成了 F(x) + x 。通过引入这种快捷结构,即使加深层,也能高效地学习。这是因为,通过快捷结构,反向传播时信号可以无衰减地传递。


图 8-12 ResNet 的构成要素:这里的"weight layer"是指卷积层

因为快捷结构只是原封不动地传递输入数据,所以反向传播时会将来自上游的梯度原封不动地传向下游。这里的重点是不对来自上游的梯度进行任何处理,将其原封不动地传向下游。因此,基于快捷结构,不用担心梯度会变小(或变大),能够向前一层传递"有意义的梯度"。通过这个快捷结构,之前因为加深层而导致的梯度变小的梯度消失问题就有望得到缓解。

ResNet 以前面介绍过的 VGG 网络为基础,引入快捷结构以加深层,其结果如图 8-13 所示。


图 8-13 ResNet:方块对应 3×3 的卷积层,其特征在于引入了横跨层的快捷结构

如图 8-13 所示,ResNet 通过以 2 个卷积层为间隔跳跃式地连接来加深层。另外,根据实验的结果,即便加深到 150 层以上,识别精度也会持续提高。并且,在 ILSVRC 大赛中,ResNet 的错误识别率为 3.5%(前 5 类中包含正确解这一精度下的错误识别率),令人称奇。

实践中经常会灵活应用使用 ImageNet 这个巨大的数据集学习到的权重数据,这称为 迁移学习 ,将学习完的权重(的一部分)复制到其他神经网络,进行再学习(fine tuning)。比如,准备一个和 VGG 相同结构的网络,把学习完的权重作为初始值,以新数据集为对象,进行再学习。迁移学习在手头数据集较少时非常有效。

3. 深度学习的高速化

3.1 需要努力解决的问题

在介绍深度学习的高速化之前,我们先来看一下深度学习中什么样的处理比较耗时。图 8-14 中以 AlexNet 的 forward 处理为对象,用饼图展示了各层所耗费的时间。

图 8-14 AlexNet 的 forward 处理中各层的时间比:左边是使用 GPU 的情况,右边是使用 CPU 的情况。图中的"conv"对应卷积层,"pool"对应池化层,"fc"对应全连接层,"norm"对应正规化层

从图中可知,AlexNex 中,大多数时间都被耗费在卷积层上。实际上,卷积层的处理时间加起来占 GPU 整体的 95%,占 CPU 整体的 89% !因此,如何高速、高效地进行卷积层中的运算是深度学习的一大课题。虽然图 8-14 是推理时的结果,不过学习时也一样,卷积层中会耗费大量时间。

3.2 基于 GPU 的高速化

GPU 原本是作为图像专用的显卡使用的,但最近不仅用于图像处理,也用于通用的数值计算。由于 GPU 可以高速地进行并行数值计算,因此 GPU 计算 的目标就是将这种压倒性的计算能力用于各种用途。所谓 GPU 计算,是指基于 GPU 进行通用的数值计算的操作。

深度学习中需要进行大量的乘积累加运算(或者大型矩阵的乘积运算)。这种大量的并行运算正是 GPU 所擅长的(反过来说,CPU 比较擅长连续的、复杂的计算)。因此,与使用单个 CPU 相比,使用 GPU 进行深度学习的运算可以达到惊人的高速化。

图 8-15 是基于 CPU 和 GPU 进行 AlexNet 的学习时分别所需的时间。


图 8-15 使用 CPU 的"16-core Xeon CPU"和 GPU 的"Titan 系列"进行 AlexNet 的学习时分别所需的时间

从图中可知,使用 CPU 要花 40 天以上的时间,而使用 GPU 则可以将时间缩短至 6 天。此外,还可以看出,通过使用 cuDNN 这个最优化的库,可以进一步实现高速化。

GPU 主要由 NVIDIA 和 AMD 两家公司提供。虽然两家的 GPU 都可以用于通用的数值计算,但与深度学习比较"亲近"的是 NVIDIA 的 GPU。实际上,大多数深度学习框架只受益于 NVIDIA 的 GPU。这是因为深度学习的框架中使用了 NVIDIA 提供的 CUDA 这个面向 GPU 计算的综合开发环境。图 8-15 中出现的 cuDNN 是在 CUDA 上运行的库,它里面实现了为深度学习最优化过的函数等。

3.3 分布式学习

虽然通过 GPU 可以实现深度学习运算的高速化,但即便如此,当网络较深时,学习还是需要几天到几周的时间。

为了进一步提高深度学习所需的计算的速度,可以考虑在多个 GPU 或者多台机器上进行分布式计算。现在的深度学习框架中,出现了好几个支持多 GPU 或者多机器的分布式学习的框架。其中,Google 的 TensorFlow、微软的 CNTK(Computational Network Toolki)在开发过程中高度重视分布式学习。以大型数据中心的低延迟·高吞吐网络作为支撑,基于这些框架的分布式学习呈现出惊人的效果。

基于分布式学习,可以达到何种程度的高速化呢?图 8-16 中显示了基于 TensorFlow 的分布式学习的效果。


图 8-16 基于 TensorFlow 的分布式学习的效果:横轴是 GPU 的个数,纵轴是与单个 GPU 相比时的高速化率

如图 8-16 所示,随着 GPU 个数的增加,学习速度也在提高。实际上,与使用 1 个 GPU 时相比,使用 100 个 GPU(设置在多台机器上,共 100 个)似乎可以实现 56 倍的高速化!这意味着之前花费 7 天的学习只要 3 个小时就能完成,充分说明了分布式学习惊人的效果。

3.4 运算精度的位数缩减

在深度学习的高速化中,除了计算量之外,内存容量、总线带宽等也有可能成为瓶颈。关于内存容量,需要考虑将大量的权重参数或中间数据放在内存中。关于总线带宽,当流经 GPU(或者 CPU)总线的数据超过某个限制时,就会成为瓶颈。考虑到这些情况,我们希望尽可能减少流经网络的数据的位数。

计算机中为了表示实数,主要使用 64 位或者 32 位的浮点数。通过使用较多的位来表示数字,虽然数值计算时的误差造成的影响变小了,但计算的处理成本、内存使用量却相应地增加了,还给总线带宽带来了负荷。

关于数值精度(用几位数据表示数值),我们已经知道深度学习并不那么需要数值精度的位数。这是神经网络的一个重要性质。这个性质是基于神经网络的健壮性而产生的。这里所说的健壮性是指,比如,即便输入图像附有一些小的噪声,输出结果也仍然保持不变。可以认为,正是因为有了这个健壮性,流经网络的数据即便有所"劣化",对输出结果的影响也较小。

计算机中表示小数时,有 32 位的单精度浮点数和 64 位的双精度浮点数等格式。根据以往的实验结果,在深度学习中,即便是 16 位的半精度浮点数 (half float),也可以顺利地进行学习 。实际上,NVIDIA 的下一代 GPU 框架 Pascal 也支持半精度浮点数的运算,由此可以认为今后半精度浮点数将被作为标准使用。

为了实现深度学习的高速化,位数缩减是今后必须关注的一个课题,特别是在面向嵌入式应用程序中使用深度学习时,位数缩减非常重要。

相关推荐
奔跑中的小象1 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南1 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang1 小时前
LangGraph 状态机实战
人工智能
刹那芳华19922 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作2 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门2 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜2 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟2 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦2 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生3 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能