主要内容

量化目标探测器和生成CUDA®代码

这个例子展示了如何为SSD车辆检测器和YOLO v2车辆检测器生成CUDA®代码,以8位整数执行推理计算。

深度学习是一种强大的机器学习技术,你可以训练一个网络来学习图像特征并执行检测任务。有几种使用深度学习的对象检测技术,如Faster R-CNN、You Only Look Once (YOLO v2)和SSD。有关更多信息,请参见使用YOLO v2进行对象检测使用SSD深度学习的目标检测

用于深度学习应用的神经网络架构包含许多处理层,包括卷积层。深度学习模型通常适用于大的标记数据集。对这些模型进行推断是计算密集型的,会消耗大量内存。神经网络使用记忆来存储输入数据、参数(权重),以及在输入通过网络传播时每一层的激活。在MATLAB中训练的深度神经网络使用单精度浮点数据类型。即使是规模很小的网络,也需要大量的内存和硬件来执行这些浮点运算。这些限制可能会阻止将深度学习模型部署到具有低计算能力和较小内存资源的设备上。通过使用较低的精度存储权重和激活,可以减少网络的内存需求。

您可以将深度学习工具箱与深度学习工具箱模型量化库支持包一起使用,通过将卷积层的权重、偏差和激活量化为8位比例整数数据类型来减少深度神经网络的内存占用。金宝app然后,您可以使用GPU Coder™为量化网络生成CUDA代码。

下载掠夺网络

下载佩带的物体探测器以避免等待培训完成。

检测=2
detectorType = 2
转变detectorType情况下1如果〜存在(“ssdResNet50VehicleExample_20a.mat”'文件') disp (“下载pretrained探测器…”);pretrowsurl =“//www.tatmou.com/金宝appsupportfiles/vision/data/ssdResNet50VehicleExample_20a.mat”;WebSave(“ssdResNet50VehicleExample_20a.mat”, pretrainedURL);结束情况下2如果〜存在(“yolov2ResNet50VehicleExample_19b.mat”'文件') disp (“下载pretrained探测器…”);pretrowsurl =“//www.tatmou.com/金宝appsupportfiles/vision/data/yolov2ResNet50VehicleExample_19b.mat”;WebSave(“yolov2ResNet50VehicleExample_19b.mat”, pretrainedURL);结束结束
下载pretrained探测器…

加载数据

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

解压缩vevicledatasetimages.zip.data =负载('车辆有绳索地球场。);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%的数据用于训练,10%用于校准,其余数据用于验证训练过的检测器。

rng (0);shuffledIndices = randperm(高度(vehicleDataset));idx = floor(0.6 * length(shuffledIndices));trainingIdx = 1: idx;trainingDataTbl = vehicleDataset (shuffledIndices (trainingIdx):);calibrationIdx = idx+1: idx+1 + floor(0.1 * length(shuffledIndices));calibrationDataTbl = vehicleDataset (shuffledIndices (calibrationIdx):);validationIdx = calibrationIdx(end)+1: length(shuffledIndices);validationDataTbl = vehicleDataset (shuffledIndices (validationIdx):);

imageDatastoreboxLabelDatastore创建用于在训练和评估期间加载图像和标签数据的数据存储。

imdsTrain = imageDatastore (trainingDataTbl {:,“imageFilename”});Bldstrain = boxlabeldataStore(trainingDatatbl(::,'车辆'));imdsCalibration = imageDatastore (calibrationDataTbl {:,“imageFilename”});BLDScalibration = BoxLabeldAtastore(CalibrationDataTBL(:,'车辆'));imdsValidation = imageDatastore (validationDataTbl {:,“imageFilename”});bldsvalidation = boxlabeldataStore(ValidationDatatbl(:,'车辆'));

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

trainingData =结合(imdsTrain bldsTrain);calibrationData =结合(imdsCalibration bldsCalibration);validationData =结合(imdsValidation bldsValidation);

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

数据=读取(CalibrationData);我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我'长方形',bbox);AnnotatedImage = IMResize(AnnotatedImage,2);数字imshow(AnnotatedImage)

定义网络参数

要减少运行示例的计算成本,请指定与运行网络所需的最小大小相对应的网络输入大小。

InputSize = [];转变detectorType情况下1输入= [300 300 3];% SSD的最小大小情况下2输入= [224 224 3];% YOLO v2的最小尺寸结束

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

numClasses =宽度(vehicleDataset) 1;

数据增加

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

使用转换来增加培训数据:

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

  • 随机缩放图像和相关的框标签。

  • 抖动图像颜色。

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

augmentedCalibrationData =变换(calibrationData @augmentVehicleData);

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

augmentedData =细胞(4,1);k = 1:4 data = read(augmentedCalibrationData);augmentedData {k} = insertShape(数据{1},'长方形'、数据{2});重置(augmentedCalibrationData);结束图蒙太奇(augmentedData,“BorderSize”10)

预处理校正数据

预处理增强校准数据以准备网络校准。

preprocessedCalibrationData =变换(augmentedCalibrationData @(数据)preprocessVehicleData(数据、inputSize));

读取预处理的校准数据。

data =阅读(preprocessedCalibrationData);

显示图像和边界框。

我={1}数据;bbox ={2}数据;annotatedImage = insertShape(我'长方形',bbox);AnnotatedImage = IMResize(AnnotatedImage,2);数字imshow(AnnotatedImage)

负载和测试净化探测器

加载预先训练好的探测器。

转变detectorType情况下1%加载预训练SSD检测器为例。pretry = load(“ssdResNet50VehicleExample_20a.mat”);探测器= pretrained.detector;情况下2%加载预先训练的YOLO v2检测器为例。pretry = load(“yolov2ResNet50VehicleExample_19b.mat”);探测器= pretrained.detector;结束

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

数据=读取(CalibrationData);i =数据{1,1};i = imresize(i,输入(1:2));[bboxes,scores] =检测(探测器,我,'临界点', 0.4);

显示结果。

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

验证浮点网络

在大量图像上评估训练的对象检测器以测量性能。计算机Vision Toolbox™提供函数来测量常见的对象检测器指标,例如平均精度(evaluateDetectionPrecision)和日志平均小姐率(evaluateDetectionMissRate).对于本例,使用平均精度度量来评估性能。平均精度提供了一个单一的数字,该数字包含了探测器进行正确分类的能力(精确)检测器找到所有相关对象的能力(回忆).

对测试数据应用与训练数据相同的预处理转换。注意,数据扩充并不应用于测试数据。理想情况下,测试数据能够代表原始数据,并且不作任何修改以进行无偏性评估。

preprocessedValidationData =变换(validationData @(数据)preprocessVehicleData(数据、inputSize));

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

检测结果=检测(检测器,预处理过透视数据,'临界点', 0.4);

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

[AP,Recall,Precision] =评估预设(检测结果,预处理过验证Data);

精度/召回(PR)曲线突出显示检测器的变化级别的精确度。理想情况下,精度在所有召回级别都是1。使用更多数据可以帮助提高平均精度,但可能需要更多的培训时间。绘制PR曲线。

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

量化网络

创建一个dlquantizer对象并指定探测器以量化。默认情况下,执行环境设置为GPU。要了解量化和部署检测器所需的产品,请参下载188bet金宝搏阅量化工作流先决条件

quantObj = dlquantizer(探测器)
quantObj = dlquantizer with properties: NetworkObject: [1×1 yolov2ObjectDetector] ExecutionEnvironment: 'GPU'

指定A中的度量标准函数dlquantizationOptions目的。

Quantopts = dlQuantizationOptions;quantopts = dlquantizationOptions('metricfcn'......{@(x)hverifydetectionResult(x,detector.network,preprocessedvalidationdata)});

使用校准函数通过样本输入来运行网络,并收集范围信息。的校准函数对网络进行操作,并在网络的卷积和全连接层中收集权重和偏差的动态范围,以及在网络的所有层中激活的动态范围。函数返回一个表。表格的每一行都包含优化网络的可学习参数的范围信息。

calResults =校准(quantObj preprocessedCalibrationData)
calResults =147×5表优化层名称网络层名称可学的/激活MinValue MaxValue  ____________________________________________ _____________________ ________________________ ________ ________ {' conv1_activation_1_relu_Weights’}{‘activation_1_relu}“权重”-9.3984 - 9.511{‘conv1_activation_1_relu_Bias}{‘activation_1_relu}“偏见”-2.64686.3474{‘res2a_branch2a_activation_2_relu_Weights}{‘activation_2_relu}“权重”-0.85967 - 0.35191{‘res2a_branch2a_activation_2_relu_Bias}{‘activation_2_relu}“偏见”-5.0999 - 5.6429{‘res2a_branch2b_activation_3_relu_Weights}{‘activation_3_relu}“权重”-0.24903 - 0.32103{‘res2a_branch2b_activation_3_relu_Bias} {' activation_3_relu '}“偏见”-2.749 - 5.1706{‘res2a_branch1_Weights}{‘bn2a_branch1}“权重”-2.4565 - 1.1476{‘res2a_branch1_Bias}{‘bn2a_branch1}“偏见”-5.3913 - 22.913{‘res2a_branch2c_activation_4_relu_Weights}{‘activation_4_relu}“权重”-1.6711 - 1.6394{‘res2a_branch2c_activation_4_relu_Bias}{‘activation_4_relu}“偏见”-6.8159 - 9.2926{' res2b_branch2a_activation_5_relu_Weights}{‘activation_5_relu}“权重”-0.46713 - 0.34267{‘res2b_branch2a_activation_5_relu_Bias}{‘activation_5_relu}“偏见”-2.9678 - 3.5533{‘res2b_branch2b_activation_6_relu_Weights}{‘activation_6_relu}“权重”-0.42871 - 0.57949{‘res2b_branch2b_activation_6_relu_Bias}{‘activation_6_relu}“偏见”-2.697 .1982 {'res2b_branch2c_activation_7_relu_Weights'} {'activation_7_relu'} "Weights" -1.1761 1.3237 {'res2b_branch2c_activation_7_relu_Bias'} {'activation_7_relu'} "Bias" -4.9467 5.1857⋮

使用证实函数对网络的卷积层中的可学习参数进行量化,并对网络进行锻炼。中定义的度量函数dlquantizationOptions对象可以在量化之前和之后比较网络的结果。

检查metricresults.result.字段的验证输出以查看量化网络的性能。结果表中的第一行包含原始浮点实现的信息。第二行包含量化实现的信息。度量函数的输出显示在metricutup.柱子。

Valresults =验证(QuantObj,PreprocessedValidationData,Quantopts)

valResults =结构体字段:NumSamples: 88 MetricResults: [1×1 struct]统计:[2×2 table]
valresults.metricresults.result.
ans =2×2表NetworkImplementation MetricOutput  _____________________ ____________ {' 浮点}0.77119 0.75244{“量子化”}

指标表明,量化将所需内存减少约75%,网络精度减少约3%。

要可视化校准统计,使用深度网络量化器应用程序。首先,保存dlquantizer目的。

保存('dlquantobj.mat''quantobj'

在MATLAB®命令窗口中,打开深网络量化器应用程序。

deepNetworkQuantizer

然后导入dlquantizer对象dq在深度网络量化器应用程序中选择新>导入dlquantizer对象

生成CUDA代码

训练并评估检测器之后,可以为ssdObjectDetector或者yolov2ObjectDetector使用GPU编码器™。有关更多详细信息,请参阅使用单次Multibox检测器进行对象检测的代码(计算机视觉工具箱)使用YOLO V2的对象检测的代码生成

cfg = coder.gpuConfig (墨西哥人的);cfg.targetlang ='c ++'%检查GPU的计算能力gpuInfo = gpuDevice;cc = gpuInfo.ComputeCapability;%创建深度学习代码生成配置对象cfg。DeepLearningConfig =编码器。DeepLearningConfig (“cudnn”);%Int8精度要求CUDA GPU具有最小计算能力% 6.1, 6.3,或更高cfg.GpuConfig.ComputeCapability = cc;cfg.DeepLearningConfig.DataType =“int8”;cfg.DeepLearningConfig.CalibrationResultFile ='dlquantobj.mat'

跑过Codegen.命令生成CUDA代码。

Codegen.-Config.cfgmynet_detectarg游戏{coder.Constant (detectorType)的(inputSize '单')}报告

当代码生成成功时,可以在MATLAB命令窗口中单击“查看报告”查看生成的代码报告。报表显示在“报表查看器”窗口中。如果代码生成器在代码生成期间检测到错误或警告,则报告将描述问题并提供问题MATLAB代码的链接。看到代码生成报告

参考文献

[1] Liu, Wei, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng Yang Fu, Alexander C. Berg。“SSD: Single Shot Multibox Detector”。在计算机视觉- ECCV 2016,由Bastian Leibe, Jiri Matas, Nicu Sebe,和Max Welling编辑,9905:21-37。Cham:施普林格International Publishing, 2016。https://doi.org/10.1007/978-3-319-46448-0_2

雷蒙德,约瑟夫和阿里·法哈迪。“YOLO9000:更好、更快、更强。”2017 IEEE计算机视觉与模式识别会议(CVPR), 6517-25。火奴鲁鲁,HI: IEEE, 2017。https://doi.org/10.1109/CVPR.2017.690

另请参阅

应用

功能

对象

相关话题