主要内容

使用R-CNN深度学习的训练对象检测器

这个例子展示了如何使用深度学习和R-CNN(带卷积神经网络的区域)训练一个对象检测器。

概述

这个例子展示了如何训练一个R-CNN对象检测器来检测停止标志。R-CNN是一种目标检测框架,它使用卷积神经网络(CNN)对图像[1]中的图像区域进行分类。R-CNN检测器不是使用滑动窗口对每个区域进行分类,而是只处理那些可能包含对象的区域。这大大减少了运行CNN时产生的计算成本。

为了演示如何训练R-CNN停止符号检测器,本示例遵循深度学习应用中常用的迁移学习工作流。在迁移学习中,在大量图像集合上训练的网络(如ImageNet[2])被用作解决新的分类或检测任务的起点。使用这种方法的优点是,预先训练的网络已经学习了一组丰富的图像特征,可适用于广泛的图像。通过对网络进行微调,这种学习可以转移到新任务中。通过对权重进行小的调整,对网络进行微调,以便对为原始任务学习的特征表示进行轻微调整,以支持新任务。

迁移学习的优点是减少了训练所需的图像数量和训练时间。为了说明这些优点,本示例使用迁移学习工作流来训练一个停止符号检测器。首先,使用CIFAR-10数据集对CNN进行预训练,该数据集有50000张训练图像。然后,只使用41张训练图像对这个预先训练的CNN进行微调,用于停止符号检测。如果没有预先训练CNN,训练停止标志检测器将需要更多的图像。

注意:此示例需要计算机视觉工具箱™、图像处理工具箱™、深度学习工具箱™和统计和机器学习工具箱™。

强烈建议使用支持cuda的NVIDIA™GPU来运行这个示例。使用GPU需要并行计算工具箱™。有关支持的计算功能的信息,请参见GPU计算的需求(并行计算工具箱)

下载CIFAR-10图像数据

下载CIFAR-10数据集[3]。该数据集包含50,000张训练图像,将用于训练CNN。

将CIFAR-10数据下载到临时目录

cifar10Data = tempdir;url =“https://www.cs.toronto.edu/ ~ kriz / cifar-10-matlab.tar.gz”;helperCIFAR10Data.download (url, cifar10Data);

加载CIFAR-10训练和测试数据。

[trainingImages, trainingLabels testImages testLabels] = helperCIFAR10Data.load (cifar10Data);

每张图片都是32x32的RGB图片,有50,000个训练样本。

大小(trainingImages)
ans =1×432 32 3 50000

CIFAR-10有10个图像类别。列出图片类别:

numImageCategories = 10;类别(trainingLabels)
ans =10×1细胞{‘飞机’}{‘汽车’}{‘鸟’}{‘猫’}{‘鹿’}{‘狗’}{‘青蛙’}{‘马’}{‘船’}{“卡车”}

您可以使用以下代码显示一些训练图像。

图缩略图= trainingImages(:,:,:,1:100);蒙太奇(缩略图)

创建卷积神经网络(CNN)

CNN由一系列层组成,其中每一层定义一个特定的计算。深度学习工具箱™提供了方便地逐层设计CNN的功能。在本例中,以下层用于创建CNN:

这里定义的网络类似于[4]中描述的网络,并以imageInputLayer.输入层定义CNN可以处理的数据的类型和大小。在本例中,CNN用于处理CIFAR-10图像,这是32x32的RGB图像:

为32x32x3 CIFAR-10图像创建图像输入层。[height,width,numChannels, ~] = size(trainingImages);imageSize = [height width numChannels];inputLayer = imageInputLayer(图象尺寸)
inputLayer = ImageInputLayer with properties: Name: " InputSize: [32 32 3] Hyperparameters DataAugmentation: 'none' Normalization: 'zerocenter' NormalizationDimension: 'auto' Mean: []

接下来,定义网络的中间层。中间层由卷积、ReLU(整流线性单元)和池化层的重复块组成。这三层构成了卷积神经网络的核心构建模块。卷积层定义滤波器权值集,在网络训练过程中更新。ReLU层为网络添加了非线性,使网络能够近似地将图像像素映射到图像的语义内容的非线性函数。池化层对流经网络的数据进行采样。在有很多层的网络中,应该谨慎地使用池化层,以避免过早地在网络中对数据进行下采样。

卷积层参数filterSize = [5 5];numFilters = 32;middleLayers = [第一个卷积层有32个5x5x3滤波器。一个添加2像素的%对称填充以确保图像边界%包含在处理中。这是必须避免的边界上的信息过早地被冲走了%网络。convolution2dLayer (filterSize numFilters,“填充”, 2)注意,过滤器的第三维度可以省略,因为它%根据网络的连通性自动推导。在这种情况是因为这一层在图像层之后,第三层。% dimension必须为3,以匹配输入中的通道数量%的形象。接下来添加ReLU层:reluLayer ()接下来是一个最大的池化层,有一个3x3的空间池化区域。%和2像素的步幅。这将对数据维度进行下采样% 32x32到15x15。maxPooling2dLayer (3“步”, 2)重复3个核心层,完成网络的中间部分。convolution2dLayer (filterSize numFilters,“填充”, 2) reluLayer () maxPooling2dLayer (3“步”2)卷积2dlayer (filterSize,2 * numFilters,“填充”, 2) reluLayer () maxPooling2dLayer (3“步”2)]
middleayers = 9x1带有图层的图层数组:1”卷积32 5 x5旋转步[1]和填充2 2 2 2 2”ReLU ReLU 3”麦克斯池3 x3马克斯池步(2 - 2)和填充(0 0 0 0)4”卷积32 5 x5旋转步[1]和填充(2 2 2 2)5”ReLU ReLU 6”马克斯池3 x3马克斯池步(2 - 2)和填充[0 0 0 0]7“卷积64 5 x5旋转步[1]和填充2 2 2 2 8”ReLU ReLU 9”麦克斯池3 x3马克斯池步(2 - 2)和填充[0 0 0 0]

通过重复这3个基本层,可以创建更深层次的网络。但是,应该减少池层的数量,以避免过早地对数据进行下采样。在网络早期的下采样会丢弃对学习有用的图像信息。

CNN的最后几层通常由全连接层和软最大损耗层组成。

finalLayers = [添加一个具有64个输出神经元的全连接层。的输出大小%这个层将是一个长度为64的数组。fullyConnectedLayer (64)添加一个ReLU非线性。reluLayer添加最后一个全连接层。此时,网络必须%产生10个信号,可用于测量是否输入图像%属于这样或那样的类别。该测量是用%后续损失层。fullyConnectedLayer (numImageCategories)添加softmax丢失层和分类层。最后一层使用%的输出全连接层来计算分类%的概率分布在图像类。在培训期间%进程中,所有的网络权值都被调优以最小化此损失%的分布。softmaxLayer classificationLayer]
finalllayers = 5x1层阵列:1”全连接64全连接二层”ReLU ReLU 3“全连接10全连接四层”Softmax Softmax 5”分类输出crossentropyex

合并输入层、中间层和最后层。

layers = [inputLayer middleelayers finalLayers]
有图层的图层数组:1”的形象输入32 x32x3图像zerocenter正常化2”卷积32 5 x5旋转步[1]和填充(2 2 2 2)3”ReLU ReLU 4”马克斯池3 x3马克斯池步(2 - 2)和填充[0 0 0 0]5“卷积32 5 x5的隆起与步幅[1]和填充(2 2 2 2)6”ReLU ReLU 7”麦克斯池3 x3马克斯池步(2 - 2)和填充[0 0 0 0]8”卷积64 5 x5旋转步[1]和填充(2 2 2 2)9”ReLU ReLU 10”马克斯Pooling 3x3 max Pooling with stride [2 2] and padding[0 0 0 0] 11”全连接64全连接层12”ReLU ReLU 13”全连接10全连接层14”Softmax Softmax 15”分类输出crossentropyex

使用标准差为0.0001的正态分布随机数初始化第一个卷积层权值。这有助于提高训练的收敛性。

层(2)。权重= 0.0001 * randn([filterSize numChannels numFilters]);

使用CIFAR-10数据训练CNN

既然已经定义了网络体系结构,那么就可以使用CIFAR-10训练数据来训练它了。首先,建立网络训练算法trainingOptions(深度学习工具箱)函数。网络训练算法采用随机梯度下降动量(SGDM),初始学习率为0.001。在训练过程中,初始学习率每8个周期降低一次(1个周期定义为通过整个训练数据集的一次完整传递)。训练算法运行了40个阶段。

注意,训练算法使用128张图像的小批处理大小。如果使用GPU进行训练,由于GPU的内存限制,这个大小可能需要降低。

设置网络训练选项选择= trainingOptions (“个”...“动量”, 0.9,...“InitialLearnRate”, 0.001,...“LearnRateSchedule”“分段”...“LearnRateDropFactor”, 0.1,...“LearnRateDropPeriod”8...“L2Regularization”, 0.004,...“MaxEpochs”现年40岁的...“MiniBatchSize”, 128,...“详细”,真正的);

训练网络使用trainNetwork(深度学习工具箱)函数。这是一个计算密集的过程,需要20-30分钟才能完成。为了在运行此示例时节省时间,将从磁盘加载预训练的网络。如果您希望自己训练网络,请设置doTraining变量设置为true。

请注意,强烈建议使用支持cuda的NVIDIA™GPU进行训练。

从磁盘加载经过训练的网络,以节省运行%的例子。将此标志设置为true以训练网络。doTraining = false;如果doTraining训练一个网络。cifar10Net = trainNetwork(trainingImages, trainingLabels, layers, opts);其他的为示例加载预先训练的检测器。负载(“rcnnStopSigns.mat”“cifar10Net”结束

验证CIFAR-10网络培训

在对网络进行培训之后,应该对其进行验证,以确保培训成功。首先,第一个卷积层的过滤器权重的快速可视化可以帮助识别任何与训练相关的即时问题。

提取第一个卷积层权值w = cifar10Net.Layers (2) .Weights;%将权重缩放到范围[0,1]以获得更好的可视化效果w =重新调节(w);图蒙太奇(w)

第一层权重应该有一些定义良好的结构。如果权重看起来仍然是随机的,那么这表明网络可能需要额外的训练。在这种情况下,如上图所示,第一层过滤器从CIFAR-10训练数据中学习了类似边缘的特征。

为了完全验证训练结果,使用CIFAR-10测试数据来衡量网络的分类准确率。较低的准确率表示需要额外的训练或额外的训练数据。本例的目标不一定是在测试集上实现100%的准确性,而是充分训练网络,以便用于训练对象检测器。

在测试集中运行网络。YTest =分类(cifar10Net, testImages);%计算精度。accuracy = sum(YTest == testLabels)/numel(testLabels)
精度= 0.7456

进一步的训练将提高准确性,但这不是训练R-CNN目标检测器的必要目的。

负荷训练数据

现在,网络在CIFAR-10分类任务中工作良好,可以使用迁移学习方法对网络进行微调,以检测停止符号。

首先加载停止标志的地面真相数据。

加载地面真相数据data =负载(“stopSignsAndCars.mat”“stopSignsAndCars”);stopSignsAndCars = data.stopSignsAndCars;更新映像文件的路径以匹配本地文件系统visiondata = fullfile (toolboxdir (“愿景”),“visiondata”);stopSignsAndCars。imageFilename = fullfile(visiondata, stopSignsAndCars.imageFilename);显示地面真实数据的摘要。总结(stopSignsAndCars)
变量:imageFilename: 41×1单元格数组字符向量stopSign: 41×1 cell carRear: 41×1 cell carFront: 41×1 cell

训练数据包含在一个表中,该表包含图像文件名和用于停止标志、汽车前部和后部的ROI标签。每个ROI标签都是围绕图像中感兴趣的对象的边界框。为了训练停止符号检测器,只需要停止符号ROI标签。必须去掉汽车前后的ROI标签:

只保留图像文件名和停止符号ROI标签stopSigns = stopSignsAndCars(:, {“imageFilename”“stopSign”});显示一个训练图像和地面真理边界框。我= imread (stopSigns.imageFilename {1});我= insertObjectAnnotation (,“矩形”, stopSigns.stopSign {1},“停车标志”“线宽”8);图imshow(我)

注意,在这个数据集中只有41个训练图像。只使用41张图像从头开始训练R-CNN对象检测器是不实际的,也不会产生可靠的停止符号检测器。因为停止符号检测器是通过微调在更大的数据集(CIFAR-10有50,000张训练图像)上预先训练的网络来训练的,所以使用更小的数据集是可行的。

火车R-CNN停止标志探测器

最后,训练R-CNN对象检测器使用trainRCNNObjectDetector.该函数的输入是地面真值表,其中包含标记的停止符号图像、预训练的CIFAR-10网络和训练选项。训练功能自动修改原有的CIFAR-10网络,将图像分为10类,变成一个网络,可以将图像分为两类:停止标志和通用背景类。

在训练过程中,使用从地面真实数据中提取的图像补丁对输入网络权值进行微调。'PositiveOverlapRange'和'NegativeOverlapRange'参数控制哪些图像补丁用于训练。正训练样本是那些与地面真理盒重叠0.5到1.0的样本,通过边界盒交集除以联合度规来测量。负训练样本是那些重叠0到0.3的样本。这些参数的最佳值应该通过在验证集上测试训练有素的检测器来选择。

R-CNN培训,强烈建议使用MATLAB工作者的并行池,以减少训练时间trainRCNNObjectDetector自动创建并使用并行池.确保在培训之前启用了并行池的使用。

为了在运行此示例时节省时间,将从磁盘加载预训练的网络。如果您希望自己训练网络,请设置doTraining变量设置为true。

请注意,强烈建议使用支持cuda的NVIDIA™GPU进行训练。

从磁盘加载经过训练的检测器以节省运行时的时间%的例子。将此标志设置为true以训练检测器。doTraining = false;如果doTraining%设置培训选项选择= trainingOptions (“个”...“MiniBatchSize”, 128,...“InitialLearnRate”1 e - 3,...“LearnRateSchedule”“分段”...“LearnRateDropFactor”, 0.1,...“LearnRateDropPeriod”, 100,...“MaxEpochs”, 100,...“详细”,真正的);训练一个R-CNN对象检测器。这需要几分钟。rcnn = trainRCNNObjectDetector(stopSigns, cifar10Net, options,...“NegativeOverlapRange”, 0.3 [0],“PositiveOverlapRange”(0.5 - 1))其他的为示例加载预先训练的网络。负载(“rcnnStopSigns.mat”“rcnn”结束

测试R-CNN停止标志检测器

R-CNN对象检测器现在可以用来检测图像中的停止标志。在测试图像上尝试一下:

%读取测试图像testImage = imread (“stopSignTest.jpg”);%检测停止标志[bboxes,分数,标签]=检测(rcnn testImage,“MiniBatchSize”, 128)
bboxes =1×4419 147 31 20
分数=0.9955
标签=明确的分类stopSign

R-CNN对象检测方法返回每个检测的对象边界框、检测评分和类标签。当检测到多个物体时,这些标签很有用,例如停止、屈服或限速标志。评分范围在0到1之间,表示检测的置信度,可以用来忽略低评分检测。

%显示检测结果[score, idx] = max(score);Bbox = bboxes(idx,:);注释= sprintf ('%s:(置信度= %f)'标签(idx),得分);outputImage = insertObjectAnnotation (testImage,“矩形”bbox,注释);图imshow (outputImage)

调试技巧

R-CNN检测器中使用的网络也可以用于处理整个测试图像。通过对大于网络输入尺寸的整个图像进行直接处理,可以生成二维的分类评分热图。这是一个有用的调试工具,因为它有助于识别图像中混淆网络的项目,并有助于提供改进训练的见解。

训练过的网络存储在R-CNN检测器中rcnn。网络
ans = SeriesNetwork with properties: Layers: [15×1 nnet.cnn.layer.Layer]

提取激活(深度学习工具箱)来自softmax层,这是网络的第14层。这些是网络扫描图像时产生的分类分数。

(rcnn featureMap =激活。网络testImage 14);softmax激活存储在一个3-D数组中。大小(featureMap)
ans =1×343 78 2

featureMap中的第三维度对应于对象类。

rcnn。一会
ans =2×1细胞{' stopSign}{‘背景’}

停止标志特征映射存储在第一个通道中。

stopSignMap = featureMap(:,:, 1);

由于网络中的下采样操作,激活输出的大小小于输入图像。要生成更好的可视化效果,请调整大小stopSignMap为输入图像的大小。这是一个非常粗略的近似,它将激活映射到图像像素,应该仅用于说明目的。

调整stopSignMap的大小以实现可视化[height, width, ~] = size(testImage);stopSignMap = imresize(stopSignMap, [height, width]);可视化叠加在测试图像上的特征图。。featureMapOnImage = imfuse(testImage, stopSignMap);图imshow (featureMapOnImage)

测试图像中的停止标志与网络激活的最大峰值很好地对应。这有助于验证R-CNN检测器中使用的CNN是否有效地学会了识别停止标志。如果有其他峰值,这可能表明训练需要额外的负面数据,以帮助防止假阳性。如果是这种情况,那么你可以在训练选项中增加“MaxEpochs”并重新训练。

总结

这个例子展示了如何使用CIFAR-10数据训练的网络来训练R-CNN停止符号对象检测器。类似的步骤也可用于训练其他使用深度学习的物体检测器。

参考文献

[1]吉尔希克,R.多纳休,T.达雷尔和J.马利克。用于精确目标检测和语义分割的丰富特征层次。2014年IEEE计算机视觉与模式识别会议论文集。哥伦布,俄亥俄州,2014年6月,580-587页。

[2]邓俊,董伟,索彻,李俊。Li, K. Li和L.飞飞。ImageNet:一个大规模的分级图像数据库。2009年IEEE计算机视觉与模式识别会议论文集。迈阿密,佛罗里达州,2009年6月,248-255页。

克里哲夫斯基,A.和G.辛顿。“从微小的图像中学习多层特征。”多伦多大学硕士论文。多伦多,加拿大,2009。

[4] https://code.google.com/p/cuda-convnet/

另请参阅

|(深度学习工具箱)|(深度学习工具箱)||||||(深度学习工具箱)||(深度学习工具箱)

相关的话题

Baidu
map