训练一个深度学习车辆检测器
这个例子展示了如何使用深度学习训练一个基于视觉的车辆检测器。
概述
利用计算机视觉进行车辆检测是跟踪自我车辆周围车辆的重要组成部分。许多自动驾驶应用都需要检测和跟踪车辆的能力,比如前方碰撞预警、自适应巡航控制和自动车道保持。自动驾驶工具箱™提供预先训练的车辆检测器(vehicleDetectorFasterRCNN
而且vehicleDetectorACF
),以实现快速原型。但是,预先训练的模型可能并不适合每个应用程序,这需要您从头开始训练。这个例子展示了如何使用深度学习从头开始训练一个车辆检测器。
深度学习是一种强大的机器学习技术,可以用来训练强大的对象检测器。目前有几种用于物体检测的深度学习技术,包括Faster R-CNN和您只看一次(YOLO) v2。方法训练一个Faster R-CNN车辆检测器trainFasterRCNNObjectDetector
函数。有关更多信息,请参见对象检测.
下载Pretrained探测器
下载一个预先训练的检测器,以避免必须等待训练完成。如果你想训练探测器,设置doTrainingAndEval
变量为true。
doTrainingAndEval = false;如果~ doTrainingAndEval & & ~存在(“fasterRCNNResNet50EndToEndVehicleExample.mat”,“文件”) disp (“下载预先训练的检测器(118 MB)…”);pretrainedURL =“//www.ru-cchi.com/supportfiles/vision/data/fasterRCNNResNet50EndToEndVehicleExample.mat”;websave (“fasterRCNNResNet50EndToEndVehicleExample.mat”, pretrainedURL);结束
加载数据集
本例使用了一个包含295张图像的小标记数据集。其中许多图像来自加州理工学院汽车1999年和2001年的数据集,可在加州理工学院计算视觉网站上获得,由Pietro Perona创建,并经许可使用。每张图片包含一个或两个标记的车辆实例。一个小的数据集对于探索Faster R-CNN训练过程是有用的,但在实践中,需要更多的标记图像来训练一个健壮的检测器。解压缩车辆图像并加载车辆地面真相数据。
解压缩vehicleDatasetImages.zipdata =负载(“vehicleDatasetGroundTruth.mat”);vehicleDataset = data.vehicleDataset;
车辆数据存储在一个两列表中,其中第一列包含图像文件路径,第二列包含车辆边界框。
将数据集拆分为训练检测器的训练集和评估检测器的测试集。选择60%的数据进行训练。用剩下的时间做评估。
rng(0) shuffledIdx = randperm(height(vehicleDataset));idx = floor(0.6 * height(vehicle - ledataset));trainingDataTbl = vehicleDataset (shuffledIdx (1: idx):);testDataTbl = vehicleDataset (shuffledIdx (idx + 1:结束):);
使用imageDatastore
而且boxLabelDatastore
创建数据存储,以便在训练和评估期间加载图像和标签数据。
imdsTrain = imageDatastore (trainingDataTbl {:,“imageFilename”});bldsTrain = boxLabelDatastore (trainingDataTbl (:,“汽车”));imdsTest = imageDatastore (testDataTbl {:,“imageFilename”});bldsTest = boxLabelDatastore (testDataTbl (:,“汽车”));
组合图像和框标签数据存储。
trainingData =结合(imdsTrain bldsTrain);testData =结合(imdsTest bldsTest);
显示其中一个训练图像和框标签。
data =阅读(trainingData);我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我“矩形”, bbox);annotatedImage = imresize (annotatedImage 2);图imshow (annotatedImage)
创建更快的R-CNN检测网络
快速R-CNN目标检测网络由一个特征提取网络和两个子网络组成。特征提取网络通常是一个经过预先训练的CNN,如ResNet-50或Inception v3。在特征提取网络之后的第一个子网是区域建议网络(RPN),它被训练来生成对象建议——图像中可能存在对象的区域。第二个子网络被训练来预测每个对象提议的实际类别。
特征提取网络通常是一个经过预先训练的CNN(有关详细信息,请参阅预训练深度神经网络(深度学习工具箱)).本例使用ResNet-50进行特征提取。您还可以使用其他预先训练过的网络,如MobileNet v2或ResNet-18,这取决于您的应用程序需求。
使用fasterRCNNLayers
创建一个快速R-CNN网络自动给定预先训练的特征提取网络。fasterRCNNLayers
需要指定几个参数化Faster R-CNN网络的输入:
网络输入大小
锚箱
特征提取的网络
首先,指定网络输入大小。在选择网络输入大小时,要考虑运行网络本身所需的最小大小、训练图像的大小以及以所选大小处理数据所产生的计算成本。在可行的情况下,选择一个接近训练图像大小且大于网络所需输入大小的网络输入大小。为了减少运行示例的计算成本,指定网络输入大小为[224 224 3],这是运行网络所需的最小大小。
inputSize = [224 224 3];
注意,本例中使用的训练图像大于224 * 224,并且大小不同,因此必须在训练之前的预处理步骤中调整图像的大小。
下一步,使用estimateAnchorBoxes
根据训练数据中对象的大小估计锚框。为了在训练前考虑图像的大小调整,调整训练数据的大小以估计锚框。使用变换
先对训练数据进行预处理,然后定义锚盒数量,并对锚盒进行估计。
preprocedtrainingdata = transform(trainingData, @(data)preprocessData(data,inputSize));numAnchors = 4;anchorBoxes = estimateAnchorBoxes (preprocessedTrainingData numAnchors)
anchorBoxes =4×296 91 68 65 150 125 38 29
有关选择锚框的更多信息,请参见根据训练数据估计锚盒(计算机视觉工具箱™)和对象检测的锚框.
现在,使用resnet50
加载一个预训练的ResNet-50模型。
featureExtractionNetwork = resnet50;
选择“activation_40_relu”
作为特征提取层。这个特征提取层输出的特征图被下采样了16倍。这个下采样量是空间分辨率和提取特征强度之间的一个很好的权衡,因为在网络中进一步提取的特征以空间分辨率为代价编码更强的图像特征。选择最优特征提取层需要进行实证分析。您可以使用analyzeNetwork
找出网络中其他潜在特征提取层的名称。
featureLayer =“activation_40_relu”;
定义要检测的类的数量。
numClasses =宽度(vehicleDataset) 1;
创建Faster R-CNN对象检测网络。
lgraph = fasterRCNNLayers (inputSize numClasses、anchorBoxes featureExtractionNetwork, featureLayer);
您可以可视化使用的网络analyzeNetwork
或从深度学习工具箱™中的深度网络设计器。
如果需要对Faster R-CNN网络体系结构进行更多的控制,请使用深度网络设计器手动设计Faster R-CNN检测网络。有关更多信息,请参见R-CNN,快速R-CNN,快速R-CNN.
数据增加
数据增强是通过训练过程中对原始数据的随机变换来提高网络精度的一种方法。通过使用数据增强,您可以为训练数据添加更多的多样性,而不必实际增加标记训练样本的数量。
使用变换
通过水平随机翻转图像和相关框标签来增强训练数据。注意,数据扩充并不应用于测试数据。理想情况下,测试数据是原始数据的代表,并且不进行修改以进行无偏的评估。
augmentedTrainingData =变换(trainingData @augmentData);
多次读取相同的图像并显示增强训练数据。
augmentedData =细胞(4,1);为k = 1:4 data = read(augmentedTrainingData);augmentedData {k} = insertShape(数据{1},“矩形”、数据{2});重置(augmentedTrainingData);结束图蒙太奇(augmentedData,“BorderSize”, 10)
训练数据进行预处理
对增强后的训练数据进行预处理,为训练做准备。
trainingData =变换(augmentedTrainingData @(数据)preprocessData(数据、inputSize));
读取预处理数据。
data =阅读(trainingData);
显示图像和框边界框。
我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我“矩形”, bbox);annotatedImage = imresize (annotatedImage 2);图imshow (annotatedImage)
火车快R-CNN
使用trainingOptions
指定网络培训选项。集“CheckpointPath”
到一个临时地点。这使得在训练过程中可以保存部分训练过的检测器。如果培训中断,例如由于停电或系统故障,您可以从保存的检查点恢复培训。
选择= trainingOptions (“个”,...“MaxEpochs”7...“MiniBatchSize”, 1...“InitialLearnRate”1 e - 3,...“CheckpointPath”, tempdir);
使用trainFasterRCNNObjectDetector
训练更快的R-CNN目标检测器,如果doTrainingAndEval
是真的。否则,加载预训练的网络。
如果doTrainingAndEval训练更快的R-CNN检测器。% *调整负重叠范围和正重叠范围以确保%训练样本与地面事实紧密重叠。[detector, info] = trainFasterRCNNObjectDetector(trainingData,lgraph,options,...“NegativeOverlapRange”, 0.3 [0],...“PositiveOverlapRange”(0.6 - 1));其他的为示例加载预先训练的检测器。pretrained =负载(“fasterRCNNResNet50EndToEndVehicleExample.mat”);探测器= pretrained.detector;结束
这个例子是在Nvidia Titan X GPU上验证的,内存为12gb。训练这个网络大约花了20分钟。训练时间因使用的硬件而异。
作为快速检查,在一个测试图像上运行检测器。请确保将图像的大小调整到与训练图像相同的大小。
我= imread (testDataTbl.imageFilename {1});我= imresize(我inputSize (1:2));[bboxes,分数]=检测(探测器,I);
显示结果。
我= insertObjectAnnotation (,“矩形”bboxes,分数);图imshow(我)
使用测试集评估检测器
在大量的图像上评估训练过的目标检测器的性能。计算机视觉工具箱™提供对象检测器评估功能,以测量常见指标,如平均精度(evaluateDetectionPrecision
)和对数平均失踪率(evaluateDetectionMissRate
).对于本例,使用平均精度度量来评估性能。平均精度提供了一个单一的数字,该数字结合了检测器做出正确分类(精度)的能力和检测器找到所有相关对象(召回)的能力。
对测试数据应用与训练数据相同的预处理变换。
testData =变换(testData @(数据)preprocessData(数据、inputSize));
在所有的测试图像上运行检测器。
如果dotraininganddeval detectionResults = detect(检测器,testData,“MinibatchSize”4);其他的为示例加载预先训练的检测器。pretrained =负载(“fasterRCNNResNet50EndToEndVehicleExample.mat”);detectionResults = pretrained.detectionResults;结束
使用平均精度度量来评估目标检测器。
[ap, recall, precision] = evaluateDetectionPrecision(detectionResults,testData);
精度/召回(PR)曲线强调了检测器在不同召回级别下的精确度。理想的精度是1在所有召回级别。使用更多的数据可以帮助提高平均精度,但可能需要更多的训练时间。绘制PR曲线。
图绘制(召回、精密)包含(“回忆”) ylabel (“精度”网格)在标题(sprintf ('平均精度= %.2f'据美联社)),
支持功能
函数data = augmentData(数据)随机翻转图像和水平边框。tform = randomAffine2d (“XReflection”,真正的);Sz = size(data{1},[1 2]);路由= affineOutputView(sz, tform);{1} = imwarp数据(数据{1}、tform“OutputView”,溃败);如果需要,消毒盒子数据。。data{2} = helperSanitizeBoxes(data{2}, sz);%经盒。{2} = bboxwarp数据(数据{2}、tform溃败);结束函数targetSize data = preprocessData(数据)将图像和边框大小调整为targetSize。Sz = size(data{1},[1 2]);规模= targetSize(1:2)。/深圳;{1} = imresize数据(数据{1},targetSize (1:2));如果需要,消毒盒子数据。。data{2} = helperSanitizeBoxes(data{2}, sz);%调整盒子。{2} = bboxresize数据(数据{2},规模);结束
参考文献
[1]任,S., K.贺,R.格什克,J.孙。《更快的R-CNN:使用区域提议网络实现实时目标检测》IEEE模式分析与机器智能汇刊.第39卷第6期,2017年6月,第1137-1149页。
[2]吉尔希克,R.多纳休,T.达雷尔和J.马利克。用于精确目标检测和语义分割的丰富特征层次。2014年IEEE计算机视觉与模式识别会议论文集.哥伦布,俄亥俄州,2014年6月,580-587页。
[3] Girshick, R。“快速R-CNN。”2015年IEEE计算机视觉国际会议论文集.圣地亚哥,智利,2015年12月,1440-1448页。
Zitnick, c.l., P. Dollar。“边缘框:从边缘定位对象建议。”欧洲计算机视觉会议.瑞士苏黎世,2014年9月,第391-405页。
[5] Uijlings, J. R. R., K. E. A. van de Sande, T. Gevers和A. W. M. Smeulders。“目标识别的选择性搜索。”国际计算机视觉杂志.2013年9月,第104卷第2期,第154-171页。