在训练卷积神经网络时,要了解如何最好地准备图像数据是具有挑战性的。
这包括在模型的训练和评估期间对像素值进行缩放以及使用图像数据增强技术。
与其测试广泛的选项,不如考虑数据准备、训练时增强和测试时增强的类型,这些类型由在具有挑战性的计算机视觉数据集(即大规模视觉识别挑战赛,或 ILSVRC,使用 ImageNet 数据集)上取得最佳性能的最先进模型使用。
在本教程中,您将发现为使用卷积神经网络的图像分类任务准备和增强照片的最佳实践。
完成本教程后,您将了解:
- 图像数据应通过减去在训练数据集上计算的每个通道的平均像素值来进行居中。
- 训练数据增强应包括随机缩放、水平翻转、亮度、对比度和颜色扰动以及随机裁剪。
- 测试时增强应包括对每张图像的多种缩放的混合,以及对每张缩放图像的多个不同系统裁剪的预测。
启动您的项目,阅读我的新书《深度学习在计算机视觉中》,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。

为卷积神经网络准备和增强图像数据的最佳实践
照片来源:Mark in New Zealand,部分权利保留。
教程概述
本教程分为五个部分;它们是:
- 顶级 ILSVRC 模型
- SuperVision (AlexNet) 数据准备
- GoogLeNet (Inception) 数据准备
- VGG 数据准备
- ResNet 数据准备
- 数据准备建议
顶级 ILSVRC 模型
在将卷积神经网络应用于图像分类时,很难确切知道如何准备图像进行建模,例如缩放或归一化像素值。
此外,可以使用图像数据增强来提高模型性能并减少泛化误差,还可以使用测试时增强来提高已拟合模型的预测性能。
与其猜测什么可能有效,不如仔细看看文献中描述的顶级模型使用的数据准备、训练时增强和测试时增强的类型。
ImageNet 大规模视觉识别挑战赛(简称 ILSVRC)是一项从 2010 年到 2017 年每年举办的竞赛,其中挑战任务使用 ImageNet 数据集的子集。该竞赛催生了一系列最先进的深度学习卷积神经网络模型,这些模型的架构和配置已成为该领域的启发式方法和最佳实践。
可以通过查阅描述在年度竞赛中获胜或表现良好的模型的论文,来发现图像数据的准备和图像增强所使用的技术。反过来,这些技术可以作为您自己图像分类任务准备图像数据的建议和最佳实践。
在接下来的章节中,我们将回顾在四个顶级模型中使用的 D数据准备和图像增强:SuperVision/AlexNet、GoogLeNet/Inception、VGG 和 ResNet。
想通过深度学习实现计算机视觉成果吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
SuperVision (AlexNet) 数据准备
多伦多大学的 Alex Krizhevsky 等人在其 2012 年论文《ImageNet Classification with Deep Convolutional Neural Networks》中开发了一种卷积神经网络,该网络在 ILSVRC-2010 和 ILSVRC-2012 图像分类任务上取得了顶级成果。
这些成果激发了人们对计算机视觉深度学习的兴趣。他们称他们的模型为 SuperVision,但后来被称作 AlexNet。
数据准备
训练数据集中的图像具有不同的尺寸,因此在使用它们作为模型输入之前必须对图像进行缩放。
将方形图像缩放到 256x256 像素。将矩形图像缩放到其最短边为 256 像素,然后从图像中裁剪出中间的 256x256 方形。注意:网络期望输入图像的形状为 224x224,通过训练增强实现。
ImageNet 由不同分辨率的图像组成,而我们的系统需要恒定的输入维度。因此,我们将图像下采样到固定的 256 x 256 分辨率。对于矩形图像,我们首先将图像缩放到最短边为 256 像素,然后从所得图像中裁剪出中心 256x256 的块。
— 使用深度卷积神经网络进行 ImageNet 分类,2012。
然后从每个像素中减去一个平均像素值,这被称为居中。据信这是按通道进行的:也就是说,平均像素值是从训练数据集中估计的,每个彩色图像的红色、绿色和蓝色通道各一个。
我们没有对图像进行其他任何预处理,除了从每个像素中减去训练集上的平均活动。因此,我们使用(居中的)原始 RGB 像素值来训练我们的网络。
— 使用深度卷积神经网络进行 ImageNet 分类,2012。
训练时增强
对训练数据集进行了图像增强。
具体来说,增强是在内存中进行的,结果并未保存,这就是现在使用该方法标准的“即时增强”。
进行的第一个增强类型是对较小的裁剪方形图像进行水平翻转,通过图像内的水平反射将其扩展到所需的边。
第一种数据增强包括生成图像平移和水平翻转。我们通过从 256x256 图像中提取随机的 224x224 块(及其水平翻转)并在这些提取的块上训练我们的网络来实现。
— 使用深度卷积神经网络进行 ImageNet 分类,2012。
进行的第二个增强类型是对图像的光照级别或亮度进行随机更改。
第二种数据增强包括改变训练图像中 RGB 通道的强度。具体来说,我们对 ImageNet 训练集上的 RGB 像素值集合进行 PCA。对于每个训练图像,我们添加找到的主成分的倍数,其幅度与相应的特征值成正比,乘以从均值为零、标准差为 0.1 的高斯分布中抽取的随机变量。
— 使用深度卷积神经网络进行 ImageNet 分类,2012。
测试时增强
进行了测试时增强,以使已拟合模型有机会做出稳健的预测。
这包括创建输入图像的五个裁剪版本和水平翻转图像的五个裁剪版本,然后平均预测结果。
在测试时,网络通过提取五个 224x224 的块(四个角块和中心块)以及它们的水平翻转(总共十个块)来做出预测,并平均网络 softmax 层在十个块上的预测。
— 使用深度卷积神经网络进行 ImageNet 分类,2012。
GoogLeNet (Inception) 数据准备
Christian Szegedy 等人(来自 Google)使用他们的 GoogLeNet 模型在目标检测方面取得了顶级成果,该模型使用了 inception 模型和 inception 架构。这种方法在他们 2014 年的论文《Going Deeper with Convolutions》中有描述。
数据准备
数据准备被描述为减去平均像素值,可能像 AlexNet 一样按通道进行居中。
我们网络中的感受野大小为 224x224,包含 RGB 颜色通道并进行均值减法。
— Going Deeper with Convolutions,2014。
第一个论文中描述的版本通常被称为 Inception v1。2015 年的后续论文《Rethinking the Inception Architecture for Computer Vision》描述了 Inception v2 和 v3。此架构的第 3 版和模型权重可在 Keras 深度学习库中找到。
在此实现中,基于开源 TensorFlow 实现,图像未进行居中;相反,像素值按图像缩放到 [-1,1] 范围,图像输入形状为 299x299 像素。此归一化和缺乏居中似乎未在最近的论文中提及。
训练时增强
训练时图像增强使用多种技术进行。
使用随机选择的纵横比(3/4 或 4/3)从训练数据集中提取随机大小的图像块。
尽管如此,在竞赛之后被验证为非常有效的一种方法包括采样图像的各种大小的块,其大小在 8% 到 100% 的图像区域之间均匀分布,其纵横比在 3/4 和 4/3 之间随机选择。
— Going Deeper with Convolutions,2014。
此外,还使用了“摄影失真”,包括对颜色、对比度和亮度等图像属性进行随机更改。
对图像进行调整以适应模型的预期输入形状,并随机选择不同的插值方法。
此外,我们开始使用随机插值方法(双线性、区域、最近邻和三次,概率相等)进行缩放。
— Going Deeper with Convolutions,2014。
测试时增强
与 AlexNet 类似,进行了测试时增强,尽管更为广泛。
每张图像在四个不同的尺度上进行重采样,从中提取多个方形裁剪,并缩放到图像的预期输入形状。结果是对给定输入图像多达 144 个版本的预测。
具体来说,我们将图像缩放到 4 个尺度,其中较短的尺寸(高度或宽度)分别为 256、288、320 和 352,然后从这些缩放图像中提取左、中、右方形(对于纵向图像,我们提取顶部、中部和底部方形)。对于每个方形,我们然后取 4 个角和中心 224x224 裁剪以及缩放到 224x224 的方形,以及它们的镜像版本。这导致每个图像有 4x3x6x2 = 144 个裁剪。
— Going Deeper with Convolutions,2014。
然后平均预测结果以做出最终预测。
对多个裁剪和所有单个分类器的 softmax 概率进行平均以获得最终预测。
— Going Deeper with Convolutions,2014。
VGG 数据准备
Karen Simonyan 和 Andrew Zisserman(来自牛津视觉几何组 VGG)使用他们的 VGG 模型在图像分类和定位方面取得了顶级成果。他们的工作在他们 2015 年的论文《Very Deep Convolutional Networks for Large-Scale Image Recognition》中有描述。
数据准备
与之前的模型一样,数据准备涉及将输入图像的形状标准化为小方形,并减去在训练数据集上计算的每个通道的像素均值。
在训练过程中,我们 ConvNets 的输入是固定大小的 224 x 224 RGB 图像。我们所做的唯一预处理就是从每个像素中减去在训练集上计算的平均 RGB 值。
— Very Deep Convolutional Networks for Large-Scale Image Recognition,2015。
训练时增强
对该模型探索了多种不同的图像缩放方法。
描述的一种方法是首先用固定但较小的图像尺寸训练模型,保留模型权重,然后将它们用作训练具有更大但仍固定尺寸的新模型的起点。这种方法旨在加快大型(第二个)模型的训练速度。
对于给定的 ConvNet 配置,我们首先使用 S = 256 训练网络。为了加速 S = 384 网络的训练,我们使用 S = 256 预训练的权重进行初始化。
— Very Deep Convolutional Networks for Large-Scale Image Recognition,2015。
另一种图像缩放方法称为“多尺度训练”,它涉及为每张图像随机选择图像尺度大小。
设置 S 的第二种方法是多尺度训练,其中每张训练图像通过从特定范围 [Smin, Smax](我们使用 Smin = 256 和 Smax = 512)中随机采样 S 来单独缩放。
— Very Deep Convolutional Networks for Large-Scale Image Recognition,2015。
在这两种训练方法中,输入图像随后被视为输入的一个较小裁剪。此外,对裁剪应用了水平翻转和颜色偏移。
为了获得固定大小的 224x224 ConvNet 输入图像,它们是从缩放的训练图像中随机裁剪的(每次 SGD 迭代每张图像一个裁剪)。为了进一步增强训练集,裁剪会经过随机水平翻转和随机 RGB 颜色偏移。
— Very Deep Convolutional Networks for Large-Scale Image Recognition,2015。
测试时增强
在训练时评估的“多尺度”方法也在测试时进行了评估,并且更普遍地称为“尺度抖动”。
创建了给定测试图像的多个不同缩放版本,对每个版本进行预测,然后平均预测结果以给出最终预测。
……我们现在评估测试时尺度抖动的影响。它包括在多个缩放版本的测试图像上运行模型(对应于不同的 Q 值),然后平均结果类的后验概率……[...] 结果……表明测试时尺度抖动可以提高性能(与在单个尺度上评估同一模型相比……
— Very Deep Convolutional Networks for Large-Scale Image Recognition,2015。
ResNet 数据准备
Kaiming He 等人(来自微软研究院)使用他们的残差网络或 ResNet 在目标检测和目标检测与定位任务方面取得了顶级成果,该成果在他们 2015 年的论文《Deep Residual Learning for Image Recognition》中有描述。
数据准备
与其他模型一样,从训练中计算的平均像素值从图像中减去,似乎按通道进行居中。
……减去每个像素的平均值。
— 用于图像识别的深度残差学习,2015年。
训练时增强
图像数据增强是多种方法的组合,借鉴了 AlexNet 和 VGG。
图像被随机缩放为小尺寸或大尺寸,这是 VGG 中使用的所谓尺度增强。然后从一个小的方形区域进行裁剪,可能伴随水平翻转和颜色增强。
图像以其较短边在 [256, 480] 范围内随机采样进行缩放,用于尺度增强 [41]。从图像或其水平翻转中随机采样 224x224 裁剪 […] 使用标准的颜色增强 [21]。
— 用于图像识别的深度残差学习,2015年。
测试时增强
测试时增强是一个标准做法,也应用于 ResNet。
与 AlexNet 类似,对测试集中的每张图像创建了 10 个裁剪,尽管这些裁剪是在每个测试图像的多个固定大小版本上计算的,从而实现了 VGG 中描述的尺度抖动。然后平均所有变体的预测。
在测试中,为了进行比较研究,我们采用标准的 10 裁剪测试。为了进行比较研究,我们采用标准的 10 裁剪测试 [21]。为了获得最佳结果,我们采用 [41, 13] 中的全卷积形式,并在多个尺度上平均得分(图像被缩放到其较短边的长度为 {224, 256, 384, 480, 640})。
— 用于图像识别的深度残差学习,2015年。
数据准备建议
鉴于对顶级性能模型中进行的数据准备的审查,我们可以总结一些在为自己的图像分类任务准备数据时应考虑的最佳实践。本节总结了这些发现。
- 数据准备。必须为输入图像选择一个固定大小,并且所有图像都必须缩放到该形状。最常见的像素缩放类型包括按通道对像素值进行居中,然后可能进行某种类型的归一化。
- 训练时增强。需要进行训练时增强,最常见的是对输入图像进行缩放和裁剪,以及对图像进行修改,如偏移、翻转和颜色更改。
- 测试时增强。测试时增强侧重于输入图像的系统性裁剪,以确保检测到输入图像中存在的特征。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
论文
- 使用深度卷积神经网络进行 ImageNet 分类, 2012.
- 使用卷积网络更深入, 2014.
- 重新思考计算机视觉的 Inception 架构, 2015.
- 用于大规模图像识别的超深度卷积网络, 2015.
- 用于图像识别的深度残差学习, 2015.
API
总结
在本教程中,您发现了为使用卷积神经网络的图像分类任务准备和增强照片的最佳实践。
具体来说,你学到了:
- 图像数据应通过减去在训练数据集上计算的每个通道的平均像素值来进行居中。
- 训练数据增强应包括随机缩放、水平翻转、亮度、对比度和颜色扰动以及随机裁剪。
- 测试时增强应包括对每张图像的多种缩放的混合,以及对每张缩放图像的多个不同系统裁剪的预测。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
谢谢 Jason,分享了这篇信息丰富的帖子!
不客气,我很高兴它有所帮助。
这篇博文写得真棒。让我对训练部分有了很多见解。谢谢。
谢谢,很高兴对您有帮助。
嗨,Jason,
一如既往,这篇文章也非常有帮助。我的训练数据集有 700 张不同分辨率的图像。我想将 2000x3000、500x400 和 300x150 的图像输入 CNN,而无需将其缩放到 VGG 或 Resnet 网络的标准尺寸。您能否给出一些建议,使其成为可能?
谢谢,
Malathi
谢谢。
不太可能。将图像缩放到模型的标准尺寸。
你好,
在 VGGNet 的测试阶段,测试图像被传入类分数图。什么是类分数图?如果您知道,能否请告知我。谢谢。
什么是“类分数图”?
我以前没听说过这个词。
在 VGGNet 论文的 3.2 测试部分中。它上面写着这句话:
结果是一个类分数图,其通道数等于类的数量,并且空间分辨率可变,取决于输入图像的大小。
我暂时不知道,抱歉。也许可以联系作者?
您好,Brownlee 博士。
非常感谢您的信息性教程。
我有一个关于在将 RGB 图像输入 CNN 之前进行 ROI(感兴趣区域)检测的问题。我的数据集由瓷砖图像组成,这些图像应根据其质量分类到某些类别。图像有一些无用部分,应该被忽略,实际上应该被裁剪。肯定需要一些预处理步骤。
是否有任何自动化方法可以识别图像中的 ROI,然后将它们输入 CNN?
我听说过 ROI-pooling,但我无法理解它是什么以及如何使用它。
您能否就此问题进行解释?
谢谢。
我暂时不知道,抱歉。我建议查阅文献。
谢谢您的回答。
不客气。
另一个想到的问题是关于是否使用裁剪图像。有些人认为不应该裁剪图像,让 CNN 自己决定。
我们是否应该使用 ROI-pooling 或 Cropping layers (Cropping2D 等) 等技术来帮助 CNN 更容易地提取特征,还是不应该使用这些技术?
非常感谢您的时间。
这实际上取决于您项目的目标,例如,您必须自己或与项目利益相关者决定。
感谢您的回答。
不客气。
谢谢您的回答。
另外,如果我想用裁剪的图像来喂养 CNN,如何最好地自动完成这个过程,即如何自动检测感兴趣的区域(在这种情况下:瓷砖的边缘而不是周围的东西)?然后将这些裁剪的图像输入 CNN?
您也许可以通过 Keras 图像数据增强实现您想要的功能。
https://machinelearning.org.cn/how-to-configure-image-data-augmentation-when-training-deep-learning-neural-networks/
我们如何找出数据增强过程后生成的图像数量?我正在使用 resnet 101,我用来训练模型的日期集大小非常小。
图像是每个批次生成的,批次大小决定了为批次生成的图像数量,该数量可以乘以每个 epoch 的步数和 epoch 的数量,以获得运行的总图像数量。
抱歉,但我对这些术语不太熟悉,能否举例说明?
感谢您的时间。
是的,您可以在此处查看完整示例。
https://machinelearning.org.cn/how-to-develop-a-convolutional-neural-network-to-classify-photos-of-dogs-and-cats/
嗨,Jason,
非常感谢您做的精彩总结!
我的理解是,对于数据预处理(至少对于表格数据来说),通常的做法是按特征减去均值并除以标准差。但是,从示例架构中,我看到它们通常只减去均值。你知道为什么吗?
我在想,这可能是因为图像数据的取值范围是[0,255],而且照片中不太可能出现高强度像素,所以通道的分布可能已经是近似高斯分布了?
谢谢,
Giles。
好问题。
我猜测是因为这样做简单且在实践中效果很好。可能还有更深层的原因,但我没有在这方面看到过任何资料。
在进行均值中心化和数据增强时,是先对原始图像进行均值中心化,然后再进行数据增强(旋转、翻转、缩放、亮度调整等),还是先进行数据增强,然后再进行均值中心化?
是的,在进行其他变换之前,像素会被缩放。
好文!谢谢!
您认为为什么大家通常使用水平翻转而不使用垂直翻转?
问候
是的,垂直翻转会让所有图像都上下颠倒——这对于大多数物体来说是没有意义的。
Keras 应用程序附带的 preprocess_function() 是否使用了这些?我不认为那些模型使用了相同的方法,而只是将像素缩放到 0-1 或 -1 到 1 的范围。您能否引用一个上述方法的实现?任何一个模型都可以。
也非常感谢您的这些博文。您和 Adrian 是我在这些方面的首选。我关注您已经两年了。
谢谢!
您可以根据自己的选择使用该函数,或者手动执行数据准备。
所以您的意思是两者相同?如果我们同时使用 rescale = 1/255 和 preprocess_input() 与 Inception 模型,会发生什么?这不会改变图像的统计数据,因为它期望的是 [-1,1] 的范围,但却得到了 [0,1] 吗?
不,每个模型在其调用 preprocess_inputs() 时可能会执行不同的操作。
感谢 Jason 带来的信息丰富且易于理解的帖子!
不客气。
“按通道的均值和标准差”是什么意思?
以及我们如何计算它们?
嗨 Henok… 以下讨论可能有助于您获得一些想法
https://discuss.pytorch.org/t/is-it-possible-to-get-per-channel-mean-and-variance-for-images-in-pytorch/63188/2
有 Keras 库可以获取我自定义数据集的按通道的均值和标准差吗?
嗨 Henoke… 我不知道有这样的库。以下内容可能对您感兴趣
https://stackify.dev/322815-normalize-training-data-with-channel-means-and-standard-deviation-in-cnn-model
谢谢你的信息!
这样做(您分享的链接)和 ImageDataGenerator 有区别吗?我们可以使用 ImageDataGenerator 来处理我们自己的自定义数据集以获取按通道的均值和标准差吗?
https://machinelearning.org.cn/how-to-normalize-center-and-standardize-images-with-the-imagedatagenerator-in-keras/