主要内容

使用SSD深度学习的目标检测

此示例显示如何训练单次侦测(SSD)。

概述

深度学习是一种强大的机器学习技术,可以自动学习检测任务所需的图像特征。有几种使用深度学习的对象检测技术,如Faster R-CNN、You Only Look Once (YOLO v2)和SSD。这个例子训练SSD车辆检测器使用trainSSDObjectDetector函数。有关更多信息,请参见对象检测

下载预用探测器

下载一个预先训练过的检测器,以避免等待训练完成。如果你想训练探测器,设置doTraining变量为真。

dotraining = false;如果〜存在dotraining &&〜存在(“ssdResNet50VehicleExample_20a.mat”“文件”) disp (“下载预训练探测器(44mb)……”);pretrainedURL ='//www.tatmou.com/金宝appsupportfiles/vision/data/ssdresnet50vehiceExample_20a.mat';websave (“ssdResNet50VehicleExample_20a.mat”, pretrainedURL);结束
下载预训练检测器(44mb)…

加载数据集

本例使用一个包含295张图像的小型车辆数据集。这些图像中有许多来自加州理工学院汽车1999年和2001年的数据集,可以在加州理工学院计算视觉中心获得网站由Pietro Perona创建并与许可一起使用。每个图像包含车辆的一个或两个标记的实例。小数据集可用于探索SSD培训过程,但在实践中,需要更多标记的图像来训练鲁棒探测器。

解压缩vehicleDatasetImages.zipdata =负载(“vehicleDatasetGroundTruth.mat”);vehicleDataset = data.vehicleDataset;

训练数据存储在一个表中。第一列包含图像文件的路径。其余的列包含车辆的ROI标签。显示数据的前几行。

车辆驾驶仪(1:4,:)
ans =4×2表imageFilename车辆  _________________________________ _________________ {' vehicleImages / image_00001.jpg '} {[220 136 35 28]} {' vehicleImages / image_00002.jpg '} {[45 175 126 61]} {' vehicleImages / image_00003.jpg '} {[45 108 120 33]} {' vehicleImages / image_00004.jpg '} {[124 112 38 36]}

将数据集分割为用于训练检测器的训练集和用于评估检测器的测试集。选择60%的数据进行训练。剩下的用于评估。

RNG(0);shuffledindices = randperm(高度(车辆达到));IDX =楼层(0.6 *长度(Shuffleddices));trainingdata =车辆升降机(Shuffledindices(1:Idx),:);testdata =车辆levlyataset(Shuffledindices(Idx + 1:结束),:);

使用imageageAtastore.boxLabelDatastore在培训和评估期间加载图像和标签数据。

imdsTrain = imageDatastore (trainingData {:,“imageFilename”});bldsTrain = boxLabelDatastore (trainingData (:,'车辆'));imdsTest = imageDatastore (testData {:,“imageFilename”});Bldstest = boxlabeldataStore(testdata(:,'车辆'));

结合图像和盒标签数据存储。

trainingdata =联合(Imdstrain,Bldstrain);testdata =组合(IMDSTEST,BLDSTEST);

显示其中一个训练图像和框标签。

data =阅读(trainingData);我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我'矩形', bbox);annotatedImage = imresize (annotatedImage 2);图imshow (annotatedImage)

创建SSD对象检测网络

SSD对象检测网络可以被认为具有两个子网。特征提取网络,其次是检测网络。

特征提取网络通常是佩带的CNN(参见普里德深度神经网络(深度学习工具箱)更多细节)。此示例使用Reset-50进行功能提取。也可以根据应用要求使用其他预磨损网络,如MobileNet V2或Reset-18。与特征提取网络相比,检测子网络是小CNN,并且由特定于SSD的一些卷积层和层组成。

使用ssdLayers功能,自动将预先训练好的ResNet-50网络修改为SSD对象检测网络。ssdLayers需要指定几个参数化SSD网络的输入,包括网络输入大小和类的数量。在选择网络输入尺寸时,要考虑训练图像的尺寸,以及在选定尺寸下处理数据所产生的计算代价。在可行的情况下,选择与训练图像大小相近的网络输入尺寸。但是,为了减少运行本例的计算成本,网络输入大小选择为[300 300 3]。在培训期间,trainSSDObjectDetector自动调整训练图像到网络输入的大小。

输入= [300 300 3];

定义要检测的对象类数。

numClasses =宽度(vehicleDataset) 1;

创建SSD对象检测网络

lgraph = ssdlayers(输入,numcrasses,“resnet50”);

您可以使用可视化网络analyzeNetwork或D.eepNetworkDesigner来自深度学习工具箱™。注意,您还可以逐层创建自定义SSD网络。有关更多信息,请参见创建SSD对象检测网络

数据增加

在训练过程中,通过随机变换原始数据来提高网络的精度。通过使用数据增广,您可以向训练数据添加更多种类,而不必实际增加已标记训练样本的数量。使用转变通过。来增加训练数据

  • 随机翻转图像和相关的框标签水平。

  • 随机缩放图像,关联的框标签。

  • 抖动图像颜色。

注意,数据扩充并不应用于测试数据。理想情况下,测试数据应该能够代表原始数据,并且不作任何修改,以便进行公正的评估。

augmentedTrainingData =变换(trainingData @augmentData);

通过多次阅读相同的图像来可视化增强训练数据。

augmentedData =细胞(4,1);k = 1:4 data = read(augmentedTrainingData);augmentedData {k} = insertShape(数据{1},'矩形',数据{2});重置(AugmentedTrainingData);结束图蒙太奇(augmentedData,'毗邻', 10)

训练数据进行预处理

预处理增强培训数据准备培训。

preprocessedtrainingdata = transform(augmentedtrainingdata,@(data)preprocessdata(数据,inputsize));

读取预处理后的训练数据。

data =阅读(preprocessedTrainingData);

显示图像和边界框。

我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我'矩形', bbox);annotatedImage = imresize (annotatedImage 2);图imshow (annotatedImage)

火车SSD对象探测器

使用培训选项指定网络培训选项。集'checkpoinspath'到一个临时的地方。这使得在训练过程中能够保存部分训练过的检测器。如果培训被中断,例如断电或系统故障,您可以从保存的检查点恢复培训。

选项=培训选项(“个”...“MiniBatchSize”, 16岁,...“InitialLearnRate”1 e 1,...“LearnRateSchedule”“分段”...“LearnRateDropPeriod”30岁的...“LearnRateDropFactor”, 0.8,...“MaxEpochs”, 300,...'verbosefrequency', 50岁,...'checkpoinspath'tempdir,...“洗牌”'每个时代');

使用trainSSDObjectDetector功能训练SSD对象检测器doTraining为真。否则,加载备用网络。

如果doTraining%培训SSD检测器。[探测器,信息] = trainsdobjectdetector(预处理托管数据,LGROP,选项);其他的%负载预训练检测器为例。pretry = load(“ssdResNet50VehicleExample_20a.mat”);探测器= pretrained.detector;结束

这个例子是在具有12gb内存的NVIDIA™Titan X GPU上验证的。如果你的GPU有更少的内存,你可能会耗尽内存。如果发生这种情况,降低'MiniBatchSize的使用培训选项函数。培训此网络使用此设置需要大约2小时。培训时间因您使用的硬件而异。

作为一个快速测试,在一个测试图像上运行检测器。

数据=读取(testdata);i =数据{1,1};i = imresize(i,输入(1:2));[bboxes,scores] =检测(探测器,我,“阈值”, 0.4);

显示结果。

我= insertObjectAnnotation (,“矩形”bboxes,分数);图imshow(我)

使用测试集评估探测器

在大量图像上评估训练的对象检测器以测量性能。Computer Vision Toolbox™提供对象检测器评估功能,以测量平均精度等常用度量(evaluateDetectionPrecision)和日志平均遗漏率(评估法律).对于本例,使用平均精度度量来评估性能。平均精度提供了一个单一的数字,该数字包含了探测器进行正确分类的能力(精确)检测器找到所有相关对象的能力(回忆).

将与训练数据的测试数据应用相同的预处理变换。注意,数据扩充并不应用于测试数据。测试数据应代表原始数据,并未被修改以进行无偏析的评估。

preprocessedTestData =变换(testData @(数据)preprocessData(数据、inputSize));

在所有测试图像上运行检测器。

detectionResults = detect(检测器,preprocestestdata,“阈值”, 0.4);

评估对象探测器使用平均精度度量。

[ap,recall,precision] = evaluateDetectionPrecision(detectionResults, preprocesedtestdata);

精度/召回(PR)曲线强调了探测器在不同召回级别上的精确程度。理想情况下,在所有召回级别上的精度都是1。使用更多的数据可以帮助提高平均精度,但可能需要更多的训练时间。

图绘制(召回、精密)包含(“回忆”)ylabel(“精度”网格)标题(sprintf ('平均精度=%.2f'据美联社)),

代码生成

探测器培训并评估后,您可以生成代码ssdObjectDetector使用GPU编码器™。有关详细信息,请参见基于单镜头多盒检测器的目标检测代码生成例子。

金宝app支持功能

功能B = augmentData (A)%应用随机水平翻转和随机X/Y缩放。盒子,如果重叠大于0.25,则在边界外缩放的%被截断。同时,抖动图像颜色。b =单元格(大小(a));我=一个{1};sz =尺寸(i);如果numel(sz)==3 && sz(3) ==3 I = jitterColorHSV(I,...'对比', 0.2,...“颜色”0,...“饱和”, 0.1,...“亮度”, 0.2);结束%随机翻转和缩放图像。tform = randomAffine2d (“XReflection”,真的,'规模',[1 1.1]);rut = AffineOutputView(SZ,TForm,“BoundsStyle”“CenterOutput”);B {1} = imwarp (tform,我“OutputView”,溃败);如果需要,%清理框。{2} = allersanitizeboxes(a {2},sz);对方框应用相同的转换。[B{2},指数]= bboxwarp ({2}, tform溃败,“OverlapThreshold”, 0.25);B{3} ={3}(指标);%仅当所有的框被扭曲时返回原始数据。如果isempty(索引)b = a;结束结束功能targetSize data = preprocessData(数据)%将图像大小调整为targetsize。Sz = size(data{1},[1 2]);规模= targetSize(1:2)。/深圳;{1} = imresize数据(数据{1},targetSize (1:2));如果需要,%清理框。数据{2}= helperSanitizeBoxes(数据{2},sz);%调整盒子。{2} = bboxresize数据(数据{2},规模);结束

参考

[1] Liu, Wei, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng Yang Fu, Alexander C. Berg。“SSD:单次发射多盒探测器。”第十四届欧洲计算机视觉大会,ECCV 2016。施普林格1 - 2016。

另请参阅

应用程序

功能

对象

相关话题