主要内容

基于R-CNN深度学习的列车目标检测器

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

概述

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

为了说明如何训练R-CNN停止标志检测器,本示例遵循深度学习应用程序中常用的迁移学习工作流。在迁移学习中,使用在大量图像集合上训练的网络,如ImageNet[2],作为起点来解决新的分类或检测任务。使用这种方法的优点是,预先训练的网络已经学习了一套丰富的图像特征,适用于广泛的图像。通过对网络的微调,这种学习可以转移到新的任务中。网络是通过对权值做小的调整来进行微调的,这样就可以稍微调整为原始任务学习到的特征表示来支持新任务。金宝app

转移学习的优势在于减少了培训所需的图像数量和培训时间。为了说明这些优势,本例使用转移学习工作流培训了停车标志检测器。首先,使用CIFAR-10数据集对CNN进行预培训,该数据集具有50000张培训图像。然后,对预培训后的CNN进行预培训仅使用41张训练图像对停车标志检测进行了微调。如果不预先训练CNN,训练停车标志检测器将需要更多的图像。

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

强烈推荐使用支持cuda的NVIDIA™GPU来运行本示例。使用GPU需要使用并行计算工具箱™。有关支持的计算能力的信息,请参见金宝appGPU支金宝app持情况(并行计算工具箱)

下载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细胞{‘飞机’}{‘汽车’}{‘鸟’}{‘猫’}{‘鹿’}{‘狗’}{‘青蛙’}{‘马’}{‘船’}{“卡车”}

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

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

创建卷积神经网络(CNN)

CNN由一系列的层组成,每一层定义一个具体的计算。深度学习工具箱™提供了一种功能,可以轻松地逐层设计CNN。在这个例子中,下面的图层被用来创建CNN:

这里定义的网络与[4]中描述的网络类似,以an开头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 dataugmentation: 'none' NormalizationDimension: 'auto' Mean: []

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

%卷积层参数filterSize = [5 5];numFilters = 32;middleLayers = [%第一个卷积层有一组32个5x5x3的滤波器。一个% 2像素的对称填充被添加,以确保图像边界%包含在处理中。这是必须避免的边界上的信息过早地被冲走了%网络。convolution2dLayer (filterSize numFilters,“填充”,2)%注意,过滤器的第三个维度可以省略,因为它%是根据网络连通性自动推导出来的。在%这种情况下,因为这个层跟随图像层,第三%尺寸必须为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)]
middleLayers=9x1层阵列,带层:1''卷积32 5x5卷积带跨步[1]和填充[2 2 2]2''ReLU ReLU 3''最大池3x3最大池跨步[2]和填充[0 0 0 0]4''卷积32 5x5卷积带跨步[1]和填充[2 2 2 2 2 2]5''ReLU ReLU 6''最大池3x3最大池跨步带跨步[2 2]和填充[0 0 0 0]7''卷积64 5x5卷积带跨步[1]和填充[2 2 2 2]8''ReLU ReLU 9''最大池3x3最大池带跨步[2]和填充[0 0 0 0]

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

CNN的最后一层通常由完全连接层和软最大损失层组成。

finalLayers = [%添加一个具有64个输出神经元的完全连接层。的输出大小%该层将是一个长度为64的数组。完全连接层(64)添加一个ReLU非线性。reluLayer%添加最后一个完全连接的层。此时,网络必须%产生10个信号,可用于测量输入图像是否正确%属于这一类或那一类。这种测量是用%随后的损失层。fullyConnectedLayer (numImageCategories)%添加softmax损耗层和分类层。最终层使用%完全连接层的输出,用于计算分类%概率分布在图像类上。在培训期间%过程中,所有网络权值都被调优,以最小化由此造成的损失%的分布。softmaxLayer classificationLayer]
finalLayers = 5x1 Layer array with layers: 1 " Fully Connected 64 Fully Connected Layer 2 " ReLU ReLU 3 " Fully Connected 10 Fully Connected Layer 4 " Softmax Softmax 5 " Classification Output crossentropyex . txt . txt . txt

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

[inputLayer middleLayers 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“马克斯池3 x3 Max池步(2 - 2)和填充(0 0 0 0)11”完全连接64完全连接层12“ReLU ReLU 13”完全连接10完全连接层14“Softmax Softmax 15"分类输出交叉

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

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

使用CIFAR-10数据训练CNN

现在已经定义了网络体系结构,可以使用CIFAR-10训练数据对其进行训练。首先,建立网络训练算法trainingOptions(深度学习工具箱)函数。网络训练算法采用动量随机梯度下降(SGDM),初始学习率为0.001。在训练过程中,初始学习率每8个epoch降低一次(1 epoch定义为对整个训练数据集进行一次完整的遍历)。训练算法运行了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,测试图像);%计算精度。= sum(YTest == testLabels)/numel(testLabels)
精度= 0.7456

进一步的训练将提高精确度,但这对于训练R-CNN目标探测器不是必需的。

负荷训练数据

既然网络在CIFAR-10分类任务中运行良好,那么可以使用转移学习方法对网络进行微调,以便进行停车标志检测。

开始加载停止标志的地面真实数据。

%加载地面真实数据data =负载(“stopSignsAndCars.mat”“停车标志和车辆”);stopSignsAndCars = data.stopSignsAndCars;%更新映像文件的路径以匹配本地文件系统visiondata = fullfile (toolboxdir (“愿景”),“visiondata”);stopSignsAndCars。imageFilename = fullfile(visiondata, stopSignsAndCars.imageFilename);%显示地面真实数据的总结总结(stopSignsAndCars)
变量:imageFilename: 41×1 cell数组的字符向量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},“停车标志”“线宽”图1(I)

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

火车R-CNN停车标志检测器

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

在训练过程中,利用地面真实数据提取的图像小块对输入网络权值进行微调。“正重叠范围”和“负重叠范围”参数控制哪些图像补丁用于训练。正训练样本是那些与地面真值框重叠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),分数);输出图像=插入对象注释(测试图像,“矩形”bbox,注释);图imshow (outputImage)

调试技巧

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

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

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

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

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

rcnn.ClassNames
ans =2×1电池{' stopSign}{‘背景’}

停车标志特征图存储在第一通道中。

stopSignMap = featureMap(:,:, 1);

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

%调整stopSignMap大小以实现可视化[height, width, ~] = size(testestimate);stopSignMap = imresize(stopSignMap, [height, width]);%可视化特征图叠加在测试图像上。featureMapOnImage = imfuse(testage, stopSignMap); / /停止信号图imshow (featureMapOnImage)

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

总结

此示例演示了如何使用使用CIFAR-10数据训练的网络训练R-CNN停车标志目标检测器。使用深度学习训练其他目标检测器也可以遵循类似步骤。

工具书类

R.格希克、J.多纳休、T.达雷尔和J.马利克。精确目标检测和语义分割的丰富特征层次2014 IEEE计算机视觉与模式识别会议论文集.Columbus, OH, June 2014, pp. 580-587。

邓娇,董伟,索切尔,吕丽君。Li, K. Li和L. Fei-Fei。ImageNet:一个大规模的分级图像数据库。2009年IEEE计算机视觉和模式识别会议记录.佛罗里达州迈阿密,2009年6月,第248-255页。

Krizhevsky, A.和G. Hinton“从微小图像中学习多层特征。”硕士论文。多伦多大学,多伦多,加拿大,2009。

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

另请参阅

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

相关的话题