主要内容

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

此示例显示如何使用深度学习和R-CNN(带有卷积神经网络的区域)训练对象探测器。

概述

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

为了说明如何训练R-CNN停止标志探测器,此示例遵循在深度学习应用中常用的传输学习工作流程。在转移学习中,在大量图像上培训的网络(例如ImageNet [2])用作解决新分类或检测任务的起点。使用这种方法的优点是佩带的网络已经学习了丰富的图像特征,适用于各种图像。通过微调网络,该学习可转换为新任务。通过对权重进行小调整来进行微调,使得为原始任务学习的特征表示来略微调整以支持新任务。万博1manbetx

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

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

强烈建议使用CUDA功能的NVIDIA™GPU来运行此示例。使用GPU需要并行计算工具箱™。有关支持的计算能力的信息,请参阅万博1manbetxGPU支万博1manbetx持情况(并行计算工具箱)

下载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个训练样本。

大小(培训剪辑)
ans =.1×432 32 3 50000

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

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

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

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

创建卷积神经网络(CNN)

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

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

%为32x32x3 cifar-10图像创建图像输入层。[高度,宽度,NumChannels,〜] =尺寸(培训码);图像= [高度宽度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;middlayers = [%第一卷积层具有32个5x5x3过滤器的银行。一种% 2像素的对称填充被添加,以确保图像边界%包含在处理中。这很重要边界上的信息过早地被冲走了% 网络。convolution2dLayer (filterSize numFilters,“填充”, 2)%注意,可以省略过滤器的第三维度,因为它基于网络的连接自动推断%。在这个案例的%是因为这层遵循图像层,第三层%维度必须为3,以匹配输入中的通道数量%的形象。%接下来添加ReLU层:rusulayer()%后面是一个最大池化层,有一个3x3的空间池区域%和2个像素的步幅。这是对数据维度的向下采样% 32x32至15x15。maxPooling2dLayer (3'走吧', 2)%重复3个核心层以完成网络的中间部分。convolution2dLayer (filterSize numFilters,“填充”,2)rululayer()maxpooling2dlayer(3,'走吧',2)卷积2dlayer (filterSize,2 * numFilters,“填充”,2)rululayer()maxpooling2dlayer(3,'走吧',2)]
middleelayers = 9x1 Layer array with layers: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“卷积64maxpooling 3x3 Max Pooling with stride [2 2] and padding [0 0 0 0]

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

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

finalLayers = [%添加一个完全连接的层,具有64个输出神经元。输出大小这一层将是一个长度为64的数组。fullyConnectedLayer (64)%添加Relu非线性。抵押者%添加最后一个完全连接的层。此时,网络必须%产生10个信号,可用于测量输入图像是否正确%属于这一类或那一类。这种测量是用%随后的损失层。全康统计(NumimageCategories)%增加softmax loss层和分类层。最后的图层使用%输出的全连接层计算的范畴%概率分布在图像类上。在培训期间%进程,调整所有网络权重以最小化此损耗%的分布。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 Middlayers 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个时期减少初始学习率(1个时期被定义为一个完整的训练数据集)。训练算法为40个时期运行。

请注意,培训算法使用Mini-Batch大小为128图像。如果使用GPU进行培训,则由于GPU上的内存约束,可能需要降低此大小。

%设置网络培训选项选择= trainingOptions (“个”...'势头', 0.9,...'italllearnrate',0.001,...“LearnRateSchedule”“分段”...'学习ropfactor',0.1,...“LearnRateDropPeriod”8...“L2Regularization”, 0.004,...“MaxEpochs”,40,...“MiniBatchSize”,128,...“详细”,真正的);

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

请注意,强烈建议使用CUDA的NVIDIA™GPU进行培训。

%培训的网络从磁盘加载以在运行时节省时间%的例子。设置该标志为true来训练网络。doTraining = false;如果用圆形%训练网络。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, testestimages);%计算精度。准确性= SUM(YTEST == TESTLABELS)/ NUMEL(TESTLABELS)
精度= 0.7456.

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

负载培训数据

既然网络在CIFAR-10分类任务中运行良好,那么迁移学习方法可以用于对网络进行微调,用于停止符号检测。

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

%加载地面真理数据data = load(“stopSignsAndCars.mat”“stopSignsAndCars”);stopsignsandcars = data.stopsignsandcars;%更新图像文件的路径以匹配本地文件系统visiondata = fullfile (toolboxdir ('想象'),“visiondata”);stopsignsandcars.imagefilename = fullfile(VisionData,StopSignSandCars.ImageFilename);%显示地面真实数据的总结摘要(STOPSIGNSANDCARS)
变量:imagefilename:41×1个字符矢量阵列停止:41×1细胞:41×1蜂窝鲤鱼: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对象检测器是不实际的,也不会产生一个可靠的停止标志检测器。因为停止标志检测器是通过微调一个网络来训练的,这个网络已经在一个更大的数据集上预先训练过(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自动创建和使用一个并行池基于您的平行的偏好设置.确保在培训之前能够使用并行池。

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

请注意,强烈建议使用CUDA的NVIDIA™GPU进行培训。

%培训的检测器从磁盘加载以节省运行时的时间%的例子。将此标志设置为true以训练检测器。doTraining = false;如果用圆形设置培训选项选项=培训选项(“个”...“MiniBatchSize”,128,...'italllearnrate'1 e - 3,...“LearnRateSchedule”“分段”...'学习ropfactor',0.1,...“LearnRateDropPeriod”, 100,...“MaxEpochs”, 100,...“详细”,真正的);%训练R-CNN对象检测器。这需要几分钟。rcnn = thathrcnnobjectdetector(stopsigns,cifar10net,选项,...'负极的贪婪', 0.3 [0],'积极透过的',[0.5 1])别的%加载预先训练的网络,为例。负载('rcnnstopsigns.mat'“rcnn”结尾

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

R-CNN物体探测器现在可以用来检测图像中的停车标志。在测试图像上试试:

读取测试图像testimage = imread(“stopSignTest.jpg”);%发现停车标志[bboxes,score,label] =检测(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检测器内使用的网络也可用于处理整个测试图像。通过直接处理大于网络的输入大小的整个图像,可以生成分类分数的2-D热映射。这是一个有用的调试工具,因为它有助于识别令人困惑网络的图像中的项目,并且可以帮助深入了解改进培训。

%训练后的网络存储在R-CNN检测器中rcnn。网络
ANS =带有属性的系列网络:图层:[15×1 nnet.cnn.layer.Layer]

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

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

featuremap中的第3维度对应于对象类。

rcnn。一会
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是否已有效学习以识别停止标志。已经有其他峰值,这可能表明培训需要额外的负数据来帮助防止误报。如果是这种情况,那么您可以在TrainingOptions中增加“MaxePochs”并重新列车。

总结

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

参考文献

[1] Girshick,R.,J. Donahue,T. Darrell和J. Malik。“丰富的特征层次结构,用于准确对象检测和语义细分。”2014 IEEE计算机视觉与模式识别会议论文集.Columbus, OH, June 2014, pp. 580-587。

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

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

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

也可以看看

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

相关的话题