火车对象检测器使用R-CNN深度学习

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

概述

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

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

转移学习的优点是减少了训练所需的图像数量和训练时间。为了说明这些优点,本例使用转移学习工作流训练一个停止标志检测器。首先,使用CIFAR-10数据集对CNN进行预训练,该数据集包含50,000张训练图像。然后这个预训练的CNN经过微调,仅用41张训练图像就可以检测到停车标志。如果不预先训练CNN,训练停止标志检测器将需要更多的图像。

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

强烈建议使用具有计算能力3.0或更高的、支持cuda的NVIDIA™GPU运行此示例。使用GPU需要并行计算工具箱™。

下载CIFAR-10图像数据

下载CIFAR-10数据集[3]。这个数据集包含50000张训练图像,将用于训练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);

每个图像是32×32的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]中描述的网络类似,以an开头imageInputLayer。输入层定义CNN可以处理的数据的类型和大小。在本例中,使用CNN处理CIFAR-10图像,图像为32x32 RGB图像:

%创建32x32x3 CIFAR-10张图像的图像输入层。[高度,宽度,numChannels,〜] =尺寸(trainingImages);IMAGESIZE = [高度宽度numChannels];inputLayer = imageInputLayer(IMAGESIZE)
inputLayer = ImageInputLayer with properties: Name: " InputSize:[32 32 3]超参数数据扩充:'none'归一化:'zerocenter'归一化维度:'auto'表示:[]

接下来,定义网络的中间层。中间层由重复的卷积、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) convolution2dLayer(filterSize,2 * numFilters,“填充”,2)reluLayer()maxPooling2dLayer(3,“步”2)]
中间层= 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)添加软最大损失层和分类层。最后一层使用%全连接层的输出来计算分类图像类的概率分布。在培训期间所有的网络权值都进行了调优,以最小化由此带来的损失%的分布。softmaxLayer classificationLayer]
1”全连接64”全连接2”ReLU全连接3”全连接10”全连接4”Softmax Softmax 5”分级输出交叉pyex

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

层= [inputLayer middleLayers finalLayers]
层= 15x1层数组与层: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”马克斯3x3 max Pooling with stride [2 2] and padding[0 0 0 0] 11 "全连接64 "全连接层12 " ReLU ReLU 13 "全连接10 "全连接层14 " Softmax Softmax 15 "分类输出cross - sentropyex

使用标准偏差为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变量如下所示为真。

需要注意的是一个支持CUDA的NVIDIA GPU™计算能力3.0或更高版本强烈建议进行培训。

.从磁盘加载一个经过训练的网络,以节省运行时的时间%的例子。将此标志设置为true以训练网络。doTraining = false;如果doTraining训练一个网络。cifar10Net = trainNetwork(trainingImages, traininglabel, 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);%计算精度。准确率= sum(YTest == testtags)/numel(testtags)
精度= 0.7456

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

负荷训练数据

现在这个网络可以很好地完成CIFAR-10分类任务,转移学习方法可以用来微调网络来进行停止信号检测。

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

%加载地面真实数据数据=负载(“stopSignsAndCars.mat”,“stopSignsAndCars”);stopSignsAndCars = data.stopSignsAndCars;%更新的路径,图像文件,以便与本地文件系统visiondata = fullfile (toolboxdir (“愿景”“visiondata”);stopSignsAndCars.imageFilename =完整文件(visiondata,stopSignsAndCars.imageFilename);显示地面真实数据的摘要摘要(stopSignsAndCars)
变量:映像文件名称:字符向量stopSign的41×1单元阵列:41×1个细胞carRear:41×1个细胞carFront:41×1个细胞

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

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

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

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

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

在训练过程中,使用从地面真实数据中提取的图像块对输入网络的权值进行微调。“正overlaprange”和“负overlaprange”参数控制用于训练的图像块。正的训练样本是那些与地面真值框重叠0.5到1.0的样本,通过边界框与联合度量的交集来测量。负的训练样本是那些重叠0到0。3的样本。这些参数的最佳值应该通过在验证集上测试经过训练的检测器来选择。

R-CNN培训,强烈建议使用并行的MATLAB工作人员池来减少培训时间trainRCNNObjectDetector自动创建和使用一个并行池的基础上平行的偏好设置。确保在培训之前启用了并行池。

为了在运行此示例时节省时间,需要从磁盘加载一个经过预处理的网络。如果您希望自己培训网络,请设置doTraining变量如下所示为真。

需要注意的是一个支持CUDA的NVIDIA GPU™计算能力3.0或更高版本强烈建议进行培训。

%A训练检测器从磁盘加载运行时,以节省时间%的例子。将此标志设置为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,选项...'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.Network
ANS = SeriesNetwork与属性:层:[15×1 nnet.cnn.layer.Layer]

提取激活来自softmax层,它是网络中的第14层。这些是网络扫描图像时产生的分类分数。

featureMap =激活(rcnn.Network,testImage,14);softmax激活被存储在一个3-D数组中。大小(featureMap)
ANS =1×343 78 2

在featureMap第三维对应于所述对象类。

rcnn.ClassNames
ANS =2×1细胞{' stopSign}{‘背景’}

stop sign feature map存储在第一个通道中。

stopSignMap = featureMap(:,:,1);

在激活输出的大小小于输入图像小由于在网络中的下采样操作。为了产生一个更好的可视化,调整大小stopSignMap输入图像的大小。这是一个非常粗略的近似值,它将激活映射到图像像素上,仅用于演示目的。

%调整大小stopSignMap可视化[高度,宽度,~]=大小(testImage);stopSignMap = imresize(stopSignMap, [height, width]);可视化测试图像上叠加的特征图。= imfuse(testImage, stopSignMap);图imshow (featureMapOnImage)

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

总结

这个例子演示了如何使用使用CIFAR-10数据训练的网络训练R-CNN停止标志对象检测器。类似的步骤可以用于使用深度学习训练其他对象检测器。

参考文献

[1] Girshick,R.,J.多纳,T.达雷尔,和J.马立克。“丰富的功能层次结构的精确物体检测及语义分割。”2014年IEEE计算机视觉与模式识别大会论文集。哥伦布,2014年6月,580-587页。

邓,J., W.董,R. Socher, L.-J。李,K.李,和L.飞飞。ImageNet:一个大型的分级图像数据库。2009年IEEE计算机视觉和模式识别会议记录。佛罗里达州,迈阿密,2009年6月,第248-255页。

[3] Krizhevsky,A.,和G.欣顿。“学习从微小的图像特征多层。”硕士论文。多伦多,加拿大多伦多,2009年大学。

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

另请参阅

||||||||||

相关的话题