主要内容

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

这个例子展示了如何训练单发探测器(SSD)。

概述

深度学习是一种强大的机器学习技术,可自动学习检测任务所需的图像特征。使用深度学习等对象检测有几种技术,例如更快的R-CNN,您只需看一次(YOLO V2)和SSD。此示例使用SSD车辆检测器使用该示例trainssdobjectdetector函数。有关更多信息,请参阅对象检测

下载Pretrained探测器

下载佩带的探测器,以避免等待培训完成。如果你想训练探测器,请设置用圆形变量为true。

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

加载数据集

此示例使用包含295个图像的小型车辆数据集。这些图像中的许多图片来自Caltech汽车1999和2001年数据集,可在Caltech计算视觉上提供网站,由Pietro Perona创作并经许可使用。每个图像包含一个或两个标记过的车辆实例。一个小的数据集是有用的探索SSD训练过程,但在实践中,需要更多标记图像训练一个鲁棒检测器。

解压缩vevicledatasetimages.zip.data = load(“vehicleDatasetGroundTruth.mat”);vevicledataset = data.vehicledataset;

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

vehicleDataset (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(高度(vehicleDataset));idx = floor(0.6 * length(shuffledinices));trainingData = vehicleDataset (shuffledIndices (1: idx):);testData = vehicleDataset (shuffledIndices (idx + 1:结束):);

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

imdsTrain = imageDatastore (trainingData {:,“imageFilename”});Bldstrain = boxlabeldataStore(TrainingData(:,“汽车”));imdstest = imageageatastore(testdata {:,“imageFilename”});bldsTest = boxLabelDatastore (testData (:,“汽车”));

合并图像和框标签数据存储。

trainingData =结合(imdsTrain bldsTrain);测试数据=合并(imdsTest, bldsTest);

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

data =阅读(trainingData);我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我“矩形”,bbox);AnnotatedImage = IMResize(AnnotatedImage,2);图imshow(AnnotatedImage)

创建SSD对象检测网络

SSD对象检测网络可以认为有两个子网。首先是特征提取网络,然后是检测网络。

特征提取网络通常是预先训练的CNN(参见预训练的深度神经网络(深度学习工具箱)更多的细节)。本例使用ResNet-50进行特征提取。其他预先训练的网络,如MobileNet v2或ResNet-18,也可以根据应用程序的要求使用。与特征提取网络相比,检测子网络是一个较小的CNN,由几个卷积层和特定于SSD的层组成。

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

inputSize = [300 300 3];

定义要检测的对象类的数量。

numclasses =宽度(车辆达到)-1;

创建SSD对象检测网络。

lgraph = ssdLayers(inputSize, numClasses,'resnet50');

您可以使用可视化的网络分析或维EEPNETWORKDESIGNER.来自深度学习工具箱™。请注意,您还可以创建一个自定义SSD网络图层。有关更多信息,请参阅创建SSD对象检测网络

数据增加

数据增强技术通过在训练过程中对原始数据进行随机变换来提高网络的精度。通过使用数据增强,您可以添加更多的变化到训练数据,而不必实际增加标记训练样本的数量。使用变换增加培训数据

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

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

  • 抖动图像颜色。

注意,数据扩充并不适用于测试数据。理想情况下,测试数据应该是原始数据的代表,并且不作修改以进行无偏评价。

augmentedTrainingData =变换(trainingData @augmentData);

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

AugmentedData = Cell(4,1​​);为了k = 1:4数据=读取(AugmentedTrainingData);AugmentedData {k} = insertshape(数据{1},“矩形”、数据{2});重置(augmentedTrainingData);结尾图蒙太奇(Augmenteddata,“BorderSize”, 10)

训练数据进行预处理

对增强的训练数据进行预处理,为训练做准备。

preprocessedTrainingData =变换(augmentedTrainingData @(数据)preprocessData(数据、inputSize));

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

数据=读取(PreprocessedTrainingData);

显示图像和边界框。

我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我“矩形”,bbox);AnnotatedImage = IMResize(AnnotatedImage,2);图imshow(AnnotatedImage)

列车SSD对象检测器

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

选择= trainingOptions ('sgdm'...'minibatchsize'16,...'italllearnrate'1 e 1,...'shownrateschedule'“分段”...“LearnRateDropPeriod”,30,...'学习ropfactor', 0.8,...“MaxEpochs”, 300,...“VerboseFrequency”, 50岁,...“CheckpointPath”,Tempdir,...'洗牌'“every-epoch”);

使用trainssdobjectdetector函数以训练SSD对象探测器如果用圆形为true。否则,加载一个预先训练好的网络。

如果用圆形%训练SSD检测器。[detector, info] = trainSSDObjectDetector(preprocesssedtrainingdata,lgraph,options);别的为示例的%负载净化探测器。pretrained =负载('ssdresnet50vehicleexample_20a.mat');探测器= pretrained.detector;结尾

这个例子是在NVIDIA™Titan X GPU上验证的,它有12gb的内存。如果你的GPU内存较少,你可能会耗尽内存。如果发生这种情况,请降低'小匹匹匹匹配' 使用trainingOptions函数。使用这个设置,训练这个网络大约花了2个小时。训练时间取决于你使用的硬件。

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

data =阅读(testData);我={1 1}数据;我= imresize(我inputSize (1:2));[bboxes,分数]=检测(探测器,我,“阈值”, 0.4);

显示结果。

我= insertObjectAnnotation (,'长方形',bboxes,得分);图imshow(i)

使用测试集评估检测器

在大量图像上评估训练后的目标检测器的性能。计算机视觉工具箱™提供对象检测器评估功能,以衡量一般指标,如平均精度(评估要求)和对数平均失误率(evaluateDetectionMissRate)。在此示例中,使用平均精度度量来评估性能。平均精度提供单个号码,其中包含探测器正确分类的能力(精度)及探测器找到所有相关物体的能力(记起)。

对测试数据应用与训练数据相同的预处理转换。注意,数据扩充并不适用于测试数据。试验数据应具有原始数据的代表性,并保持不变以进行无偏评价。

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

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

检测=检测(检测器,预处理edtestdata,“阈值”, 0.4);

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

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

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

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

代码生成

一旦对检测器进行了训练和评估,您就可以为ssdobjectdetector使用GPU编码器™。更多信息请参见使用单次Multibox检测器进行对象检测的代码的例子。

金宝app支持功能

函数b = upmentdata(a)%应用随机水平翻转,随机X / Y缩放。得到的盒子如果重叠大于0.25,则缩放到边界外的%将被剪切。同时,%抖动图像颜色。B =细胞(大小(A));我= {1};深圳=大小(I);如果numel(sz)== 3 && sz(3)== 3 i = jittercolorhsv(i,...“对比”, 0.2,...'色调',0,...“饱和”, 0.1,...“亮度”,0.2);结尾%随机翻转和缩放图像。tform = randomAffine2d (“XReflection”,真的,“规模”1.1 [1]);tform溃败= affineOutputView(深圳,'裸机'“CenterOutput”);b {1} = imwarp(i,tform,'OutputView',溃败);%消毒盒子,如果需要。A{2} = helperSanitizeBoxes(A{2}, sz);%匹配到框相同的变换。[B{2},指数]= bboxwarp ({2}, tform溃败,“OverlapThreshold”,0.25);b {3} = {3}(索引);%仅当所有框被扭曲移除时才返回原始数据。如果isempty(indices) B = A;结尾结尾函数targetSize data = preprocessData(数据)%调整图像和边界框的大小为targetSize。Sz = size(data{1},[1 2]);规模= targetSize(1:2)。/深圳;{1} = imresize数据(数据{1},targetSize (1:2));%消毒盒子,如果需要。数据{2} = allersanitizedboxes(数据{2},sz);%调整盒子。{2} = bboxresize数据(数据{2},规模);结尾

参考文献

[1]刘,魏,龙卷风犬,丹麦特·埃哈,基督教斯德,斯科特芦苇,郑阳富,亚历山大C.伯格。“SSD:单次拍摄多杆探测器。”第14届欧洲电脑愿景会议,ECCV 2016年。Springer Verlag,2016年。

也可以看看

应用程序

功能

对象

相关的话题