主要内容

量化层在对象检测器和生成CUDA代码

这个示例之前被命名为“量化对象检测器和生成CUDA代码”,但在R2022a中重新命名,以避免与由数字转换(深度学习工具箱)函数。代码生成不支持量化的深度神经网络产生数字转换函数。

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

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

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

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

下载Pretrained网络

下载一个预先训练的对象检测器,以避免必须等待训练完成。

detectorType =2
detectorType = 2
开关detectorType情况下1如果~ (“ssdResNet50VehicleExample_20a.mat”“文件”) disp (“下载pretrained探测器…”);pretrainedURL =“//www.ru-cchi.com/supportfiles/vision/data/ssdResNet50VehicleExample_20a.mat”;websave (“ssdResNet50VehicleExample_20a.mat”, pretrainedURL);结束情况下2如果~ (“yolov2ResNet50VehicleExample_19b.mat”“文件”) disp (“下载pretrained探测器…”);pretrainedURL =“//www.ru-cchi.com/supportfiles/vision/data/yolov2ResNet50VehicleExample_19b.mat”;websave (“yolov2ResNet50VehicleExample_19b.mat”, pretrainedURL);结束结束

加载数据

本例使用了一个包含295张图像的小型车辆数据集。这些图片大多来自加州理工学院赛车1999年和2001年的数据集,由Pietro Perona创建,并经许可使用。每张图片包含一个或两个标记的车辆实例。一个小的数据集对于探索训练过程是有用的,但在实践中,需要更多的标记图像来训练一个健壮的检测器。提取车辆图像,加载车辆地面真实数据。

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

为培训、校准和验证准备数据

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

vehicleDataset (1:4,:)

将数据集分为训练集、验证集和测试集。选择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):);

使用imageDatastore而且boxLabelDatastore创建数据存储,以便在训练和评估期间加载图像和标签数据。

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);

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

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

定义网络参数

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

inputSize = [];开关detectorType情况下1 inputSize = [300 300 3];SSD的最小大小情况下2 inputSize = [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检测器。pretrained =负载(“ssdResNet50VehicleExample_20a.mat”);探测器= pretrained.detector;情况下2为示例加载预先训练的YOLO v2检测器。pretrained =负载(“yolov2ResNet50VehicleExample_19b.mat”);探测器= pretrained.detector;结束

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

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

显示结果。

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

验证浮点网络

在大量的图像上评估训练过的目标检测器的性能。计算机视觉工具箱™提供了测量常见对象检测器指标的功能,如平均精度(evaluateDetectionPrecision)和对数平均失踪率(evaluateDetectionMissRate).对于本例,使用平均精度度量来评估性能。平均精度提供了一个单一的数字,它包含了探测器做出正确分类的能力(精度)和探测器找到所有相关物体的能力(回忆).

对测试数据应用与训练数据相同的预处理变换。注意,数据扩充没有应用到测试数据。理想情况下,测试数据是原始数据的代表,并且不进行修改以进行无偏性评估。

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

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

detectionResults = detect(检测器,预处理的验证数据,“阈值”, 0.4);

用平均精度度量对目标检测器进行评估。

[据美联社、召回、精密]= evaluateDetectionPrecision (detectionResults preprocessedValidationData);

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

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

生成网络校准结果文件

创建一个dlquantizer对象,并指定要量化的检测器。默认情况下,执行环境设置为GPU。要了解量化检测器并将其部署到GPU环境2022世界杯八强谁会赢?所需的产品,请参见量化工作流先决条件(深度学习工具箱)

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

在a中指定度量函数dlquantizationOptions对象。

quantOpts = dlquantizationOptions;quantOpts = dlquantizationOptions (“MetricFcn”...{@ (x) hVerifyDetectionResults (x,探测器。网络、preprocessedValidationData)});

使用校准函数用样本输入练习网络并收集范围信息。的校准函数练习网络,收集网络卷积层和全连通层的权值和偏差的动态范围,以及网络各层激活的动态范围。函数返回一个表。表的每一行都包含优化网络的可学习参数的范围信息。

calResults =校准(quantObj preprocessedCalibrationData)

使用验证函数量化网络卷积层中的可学习参数,并对网络进行训练。函数中定义的度量函数dlquantizationOptions对象,比较量化前后的网络结果。

检查MetricResults。结果字段的验证输出,查看优化后网络的性能。结果表中的第一行包含原始浮点实现的信息。第二行包含量化实现的信息。度量函数的输出显示在MetricOutput列。

valResults =验证(quantObj preprocessedValidationData quantOpts)

valResults =结构体字段:NumSamples: 88 MetricResults: [1×1 struct] Statistics: [2×2 table]
valResults.MetricResults.Result

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

要可视化校准统计数据,使用深度网络量化应用程序dlquantizer对象。

保存(“dlquantObj.mat”“quantObj”

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

deepNetworkQuantizer

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

生成CUDA代码

训练和评估检测器之后,可以为ssdObjectDetectoryolov2ObjectDetector使用GPU编码器™。有关更多细节,请参见单次多盒检测器目标检测的代码生成(计算机视觉工具箱)而且基于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配置cfgmynet_detectarg游戏{coder.Constant (detectorType)的(inputSize '单')}报告

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

参考文献

[1]刘,魏,德拉戈米尔·安格洛夫,杜米特鲁·埃尔汉,克里斯蒂安·舍格迪,斯科特·里德,程杨富,亚历山大·C.伯格。SSD:单发多盒探测器《计算机视觉- ECCV 2016》,由Bastian Leibe, Jiri Matas, Nicu Sebe和Max Welling编辑,9905:21-37。chamam:施普林格国际出版,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

另请参阅

应用程序

功能

对象

相关的话题

Baidu
map