主要内容

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

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

概述

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

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

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

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

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

下载CIFAR-10图像数据

下载CIFAR-10数据集[3]。该数据集包含5万张训练图像,将用于训练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个图像类别。列出图像类别:

numimagecategcategories = 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 =[高度宽度numChannels];inputLayer = imageInputLayer(imageSize)
inputLayer = ImageInputLayer with properties: Name: " InputSize:[32 32 3]超参数DataAugmentation: 'none'归一化:'zerocenter' NormalizationDimension: 'auto' Mean: []

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

%卷积层参数filterSize = [5 5];numFilters = 32;中间层= [第一个卷积层有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)]
midelayers = 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分类层
finalLayers = 5x1分层阵列:1 "全连接64全连接Layer 2 " ReLU ReLU 3 "全连接10全连接Layer 4 " Softmax Softmax 5

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

layers = [inputLayer middleLayers finalLayers]
图层数组= 15x11”的形象输入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]和padding[0 0 0 0 0] 11 "全连接64全连接层12 " ReLU ReLU 13 "全连接10全连接层14 " Softmax Softmax 15 " Classification Output crossentropyex

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

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

使用CIFAR-10数据训练CNN

现在已经定义了网络架构,可以使用CIFAR-10训练数据对其进行训练。首先,建立网络训练算法trainingOptions(深度学习工具箱)函数。网络训练算法使用带有动量的随机梯度下降(SGDM),初始学习率为0.001。在训练过程中,初始学习率每8个epoch降低一次(1 epoch定义为对整个训练数据集的一次完整通过)。训练算法运行40个epoch。

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

设置网络培训选项opts = 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 = rescale(W);图蒙太奇(w)

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

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

在测试集中运行网络。YTest = category (cifar10Net, testImages);计算准确率。accuracy = sum(YTest == testLabels)/numel(testLabels)
准确度= 0.7456

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

负荷训练数据

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

首先加载停止标志的ground truth数据。

加载真实数据数据=负载(“stopSignsAndCars.mat”“stopSignsAndCars”);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”});显示一张训练图像和地面真值包围框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网络和训练选项。训练功能自动将原来将图像分为10类的CIFAR-10网络修改为可以将图像分为2类的网络:停止标志和通用背景类。

在训练过程中,使用从地面真实数据中提取的图像补丁对输入网络权重进行微调。“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 0.3],“PositiveOverlapRange”(0.5 - 1))其他的为示例加载预训练的网络。负载(“rcnnStopSigns.mat”“rcnn”结束

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

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

读取测试图像testImage = imread(“stopSignTest.jpg”);%检测停止标志[bboxes,score,label] = detect(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)', label(idx), score);outputImage = insertObjectAnnotation(testImage,“矩形”, bbox,注释);图imshow (outputImage)

调试技巧

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

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

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

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

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

rcnn。一会
ans =2×1细胞{'stopSign'} {'Background'}

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

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停止标志对象检测器。可以遵循类似的步骤来训练其他使用深度学习的对象检测器。

另请参阅

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

相关的话题

参考文献

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

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

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

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