Deep Learning Note: 4-6 使用卷积神经网络的建议

1. 使用开源实现

  前面介绍了很多优秀的卷积神经网络架构,但要根据论文复现这些网络往往非常复杂,不但需要实现各种细节,还需要做超参数调优,最终得到的性能可能还会与原网络有差异。幸运的是,很多研究者会将自己的工作开源。在选定了要使用的网络后,可以先在网上(如 Github)查找该网络的开源实现。另外,很多网络的训练都需要大量的数据和很强的计算能力,通过使用开源实现,可以直接利用别人训练好的模型,以此作为预训练的模型进行迁移学习。

2. 使用开源实现

  对于计算机视觉领域,可以在网上找到大量的训练数据,比如 Image NetCOCoPASCAL 等等。很多人使用海量的数据,应用现代的计算设备,花费大量时间训练和调优,得到高性能的模型并开源出来。对于计算机视觉方面的应用,相比于从头开始训练,从网上下载开源实现和训练好的权重,以此初始化自己的模型并进行迁移学习,可以极大地提高工作效率。

  举例来说,想要训练一个分类器,用于识别自己养的两只猫 Tigger 和 Misty,分类器输出为一个 $3 \times 1$ 的向量,表示输入图像是 Tigger、是 Misty、或者都不是。由于只是识别自己养的猫,可用的数据量很少。对于这个任务,可以先从网上找一个对象识别模型的开源实现及模型权重等参数,比如找到一个用 ImageNet 数据训练的模型如图 1 所示,ImageNet 的数据有 1000 个分类,该模型输出的预测为一个 $1000 \times 1$ 的向量。

图 1

图 1

  把原模型的 Softmax 层替换为我们自己的实现,输出一个 $3 \times 1$ 的向量,如图 2。

图  2

图 2

  然后保持之前网络的结构和参数不变,使用我们自己任务的数据,仅训练这个新的 Softmax 层上的参数。因为原模型已经具有很好的性能,迁移学习时,即便我们自己任务上的数据不是很多,也可以获得很好的效果。

  由于我们只训练 Softmax 层,而保持 Softmax 之前的网络结构和参数不变,可以把 Softmax 之前的各层看成是一个固定的函数。各个训练样本在 Softmax 之前一层输出的激活值时固定的,可以预先计算并保存到本地,之后训练 Softmax 层时直接读取本地预先计算的结果,以此减少计算量,加快训练速度。

  上面展示的是可用数据量很少的情况,只替换了 Softmax 层。如果可用的数据量很大,则可以在替换 Softmax 层之后,保持原网络中较少的层数不变,如前 $n$ 层,并对之后的网络进行训练。对于网络中要训练的部分,除了 Softmax 层要替换外,对于其他层,即可以保留其原有结构,只是重新训练参数,也可以完全替换为其他结构的网络再做训练。要训练的层数可以根据可用数据的多少来选择,可用数据越多,就可以训练更多的层数。如果数据特别多,则可以使用开源实现中的参数初始化网络,并对整个网络进行训练(也需要替换 Softmax 层)。

  在计算机视觉领域,几乎总可以通过迁移学习将已有模型学习到的知识迁移到目标问题上,从头开始训练需要有海量的数据和超强的计算能力。

3. 数据扩充

  计算机视觉问题通常需要大量的数据,通过数据扩充(Data Augmentation)可以增加训练数据,提高系统性能。

  镜像是一种最简单的数据扩充方法,即将一张图像翻转,得到新的图像,如图 3,一张猫的图片水平镜像后还是一张猫的图片。

图 3

图 3

  随机裁剪也可以扩充数据,即从一张图像中随机裁剪出小块的图像,如图 4。随机裁剪的一个问题是,如果裁剪尺寸过小、位置不合适,则可能没有裁剪到主要目标,导致样本与标签不符,例如对一张猫的图像做随机裁剪,只裁剪到了背景,没有裁剪到猫。

图 4

图 4

  此外,还可以通过旋转、变形、局部扭曲等方式数据扩充。

  色彩偏移(Color Shifting)是另一种数据扩充方式,即在原图像的颜色上加入不同的失真。例如将一张图片 RGB 三个通道的值分别加入不同的偏移,得到一张新的图片,如图 5 所示。

图 5

图 5

  在实际场景中,对于同一个物体,在不同的环境(如光照)下拍摄可能会具有不同的色彩,而物体本身即图像的标签并不会变。色彩偏移相当于模拟了此种情况,不管是在中午还是在傍晚拍摄一只猫,照片中的都是猫。使用这样的数据进行训练,可以让算法能更好地适应色彩的变化。

  这里为了展示效果更明显,使用了很大的失真,实在际应用中,加入失真的具体数值可以从特定的分布中获取,其值通常很小。色彩偏移的一种实现方式是使用主成分分析(Principal Component Analysis,PCA),称为 PCA Color Augmentation,在 AlexNet 的论文中给出了具体实现。其主要思路是根据图像中 RGB 的分布来决定要添加的偏移量,例如图像中红色和绿色的成分比较多,蓝色的成分比较少,则在做色彩偏移时,在图像的 R 和 G 通道上加入较多的偏移,在 B 通道上加入较少的偏移,以此保持图像的整体色调不变。

  在应用数据扩充时,通常使用一个或多个 CPU 线程从磁盘中读取数据,并使用各种扩充方式扩充数据,生成一个批量的数据,交给其他 CPU 线程/进程或 GPU 来进行训练,数据扩充和模型训练并行进行。

  数据扩充也会带来一些超参数,比如随机裁剪中裁剪的大小,色彩偏移中偏移量的获取方式等。也可以使用开源实现,并在其基础上做进一步的调优。

4. 计算机视觉的现状

  图 6 展示了各种机器学习问题和目前在该问题上可用的数据量,横轴表示可用数据量,从左向右数据量逐渐增加。

图 6

图 6

  目前在语音识别(Speech Recognition)问题上有相当的数据量可以使用。在图像识别(Image Recognition)问题上,虽然也有相当多的数据,但图像识别本身是一个非常复杂的问题,对于其复杂度来说,数据量仍显不够。而对于对象检测(Object Detection)问题,可用的数据就更少了。注意区分图像识别和对象检测的区别:图像识别只要识别图像中的对象是什么,对象检测不光要识别目标对象,还要找到其位置。对象检测训练数据的标签要包含对象的位置,手动标记的成本更高,因此可用的数据量更少。

  当有很多数据时,人们倾向于使用更简单的网络,更少使用手工设计,即使用一个很大的网络,不手工设计特征,而是让模型自己去学习。当数据量不足时,人们则倾向于使用更多的手工设计,将人类的知识注入到模型中。

  通常来说,学习算法可以从两个途径获得知识,一个途径是有标签的数据,另一个途径是手工设计的特征、网络结构或其他组件。当数据不足时,就得更加依赖于手工设计。由于计算机视觉领域的问题通常十分复杂,即便现在已经有了很多数据,也总是不够,因此计算机视觉领域一直以来都比其他领域更依赖于手工设计。也正是因此,在计算机视觉领域出现了很多复杂的网络架构,来弥补数据的不足。迁移学习也是解决数据不足问题的有效方法。

  计算机视觉领域有很多标准测试数据集和比赛,在这些数据集上获得优异的性能有助于发表论文,但有时候也会在论文中看到一些方法,专门用于提高算法在标准测试数据集上的性能,而通常不会在生产环境中使用。以下针对提高算法在标准测试数据集上的性能和赢得比赛,给出一些建议:

  • 综合(Ensembling):在决定要使用的网络后,独立地训练多个网络,对它们的输出求平均。例如分别随机初始化 5 个网络,相互独立地进行训练,最终的输出是 5 个网络输出的平均值。这种方法大约可以提高 1% ~ 2% 的性能,但由于使用了多个网络,计算量也会成倍增长,因此这种方法不会用在生产系统中。

  • 在测试时使用 Multi-Crop:对于一个测试样本,通过裁剪生成多个版本的测试图像,然后使用这些图像进行测试并对结果求平局值。例如一种称为 10-Crop 的方法,先将图像镜像,然后分别对原图像和镜像图像的中间、上、下、左、右四个区域进行裁剪,得到 10 个图像(如图 7),分别由分类器进行预测,并对结果求平均。

图 7

图 7

  在计算机视觉领域,在一个问题上具有很好性能的网络,通常也能用于其他问题并获得很好地性能。在构建实际的系统时,使用现有的成熟的网络结构,尽可能地使用开源实现,通常是一个很好的开始。使用别人预先训练好的模型进行迁移学习,根据自己的数据进行调优,可以节省大量的训练和调优时间,尤其适用于数据量较少的情况。