主要内容

使用YOLO v3深度学习的目标检测代码生成

这个例子展示了如何生成CUDA®MEX一个你只看一次(YOLO) v3对象检测器与自定义层。YOLO v3在YOLO v2的基础上进行了改进,增加了多尺度的检测,帮助检测更小的对象。此外,将用于训练的损失函数分离为边界盒回归的均方误差和用于目标分类的二叉交叉熵,有助于提高检测精度。本例中使用的YOLO v3网络是从使用YOLO v3深度学习的对象检测示例在计算机视觉工具箱(TM)。有关更多信息,请参见使用YOLO v3深度学习的对象检测(计算机视觉工具箱)

第三方的先决条件

要求

  • CUDA支持NVIDIA®GPU和兼容驱动程序。

可选

对于非mex构建,如静态、动态库或可执行文件,本例有以下附加要求。

验证GPU环境

要验证运行此示例的编译器和库是否正确设置,请使用coder.checkGpuInstall函数。

envCfg = coder.gpuEnvConfig (“主机”);envCfg。DeepLibTarget =“cudnn”;envCfg。DeepCodegen = 1;envCfg。安静= 1;coder.checkGpuInstall (envCfg);

YOLO v3意思网络

本例中的YOLO v3网络基于挤压网(深度学习工具箱),采用了SqueezeNet中的特征提取网络,并在末端增加了两个检测头。第二个检测头的尺寸是第一个检测头的两倍,所以它能更好地检测小物体。注意,可以根据要检测的物体的大小指定任意数量的不同尺寸的探测头。YOLO v3网络使用使用训练数据估计的锚盒,以获得更好的对应于数据集类型的初始先验,并帮助网络学习准确预测锚盒。有关锚框的信息,请参见用于对象检测的锚盒(计算机视觉工具箱)

本示例中的YOLO v3网络如下图所示。

每个检测头预测边界框坐标(x, y,宽度,高度),对象置信度,以及各自锚框遮罩的类概率。因此,对于每个检测头,最后卷积层输出滤波器的个数等于锚盒掩码的个数乘以每个锚盒的预测元素个数。检测头组成网络的输出层。

预先训练的YOLO v3网络

本示例使用yolov3SqueezeNetVehicleExample_21a.zip预训练的YOLO v3网络文件。这个文件大约有9MB大小。从MathWorks网站下载该文件,然后解压缩该文件。

文件名= matlab.internal.examples.downloadSuppor金宝apptFile (“视觉/数据/”“yolov3SqueezeNetVehicleExample_21a.zip”);解压缩(文件名);

本示例中使用的YOLO v3网络是使用中描述的步骤进行训练的使用YOLO v3深度学习的对象检测(计算机视觉工具箱)

matFile=“yolov3SqueezeNetVehicleExample_21a.mat”;pretrained =负载(matFile);网= pretrained.net;

YOLO v3网络使用resize2dLayer(图像处理工具箱)通过按2的比例因子复制相邻像素值来调整二维输入图像的大小。resize2DLayer是作为支持代码生成的自定义层实现的。金宝app有关更多信息,请参见定义用于代码生成的自定义深度学习层(深度学习工具箱)

注意:您也可以通过计算机视觉工具箱使用预训练检测器网络™ YOLO v3对象检测支持包的模型。金宝app

要使用这个预先训练过的网络,您必须首先从附加资源管理器中安装用于YOLO v3对象检测的计算机视觉工具箱模型。有关安装附加组件的详细信息,请参见获取和管理附加组件

然后,保存网络从yolov3ObjectDetector对象,然后继续。例如,

探测器= yolov3ObjectDetector (“darknet53-coco”);网= detector.Network;matFile=“预训练的Yolov3检测器。mat”;保存(matFile,“净”);

yolov3Detect入口点函数

yolov3Detect入口点函数取输入图像并将其传递给经过训练的网络进行预测yolov3Predict作用这个yolov3Predict函数将网络对象从mat -文件加载到持久变量中,并在后续的预测调用中重用该持久对象。具体来说,函数使用dlnetwork(深度学习工具箱)表示在使用YOLO v3深度学习的对象检测(计算机视觉工具箱)的例子。从YOLO v3网格单元坐标得到的预测yolov3Predict然后使用支持函数将调用转换为边界框坐标金宝app生成锚applyAnchorBoxOffsets

类型(“yolov3Detect.m”
function [bboxes,scores,labelsIndex] = yolov3Detect(matFile, im,…networkInputSize、networkOutputs confidenceThreshold,……yolov3Detect函数检测图像中的边界框、分数和% labelsIndex。Preprocess Data该示例将所有预处理转换应用到训练期间应用的数据集%,数据增强除外。由于示例%使用了预先训练的YOLO v3网络,因此输入数据必须是原始数据的代表性%,并且不进行修改,以便进行无偏评估。具体来说,下面的预处理操作被应用到%输入数据。% 1。将图像调整为网络输入的大小,因为图像比networkInputSize大%。2.在%[0 1]范围内缩放图像像素。 3. Convert the resized and rescaled image to a dlarray object. im = dlarray(preprocessData(im, networkInputSize), "SSCB"); imageSize = size(im,[1,2]); %% Define Anchor Boxes % Specify the anchor boxes estimated on the basis of the preprocessed % training data used when training the YOLO v3 network. These anchor box % values are same as mentioned in "Object Detection Using YOLO v3 Deep % Learning" example. For details on estimating anchor boxes, see "Anchor % Boxes for Object Detection". anchors = [ 41 34; 163 130; 98 93; 144 125; 33 24; 69 66]; % Specify anchorBoxMasks to select anchor boxes to use in both the % detection heads of the YOLO v3 network. anchorBoxMasks is a cell array of % size M-by-1, where M denotes the number of detection heads. Each % detection head consists of a 1-by-N array of row index of anchors in % anchorBoxes, where N is the number of anchor boxes to use. Select anchor % boxes for each detection head based on size-use larger anchor boxes at % lower scale and smaller anchor boxes at higher scale. To do so, sort the % anchor boxes with the larger anchor boxes first and assign the first % three to the first detection head and the next three to the second % detection head. area = anchors(:, 1).*anchors(:, 2); [~, idx] = sort(area, 'descend'); anchors = anchors(idx, :); anchorBoxMasks = {[1,2,3],[4,5,6]}; %% Predict on Yolov3 % Predict and filter the detections based on confidence threshold. predictions = yolov3Predict(matFile,im,networkOutputs,anchorBoxMasks); %% Generate Detections % indices corresponding to x,y,w,h predictions for bounding boxes anchorIndex = 2:5; tiledAnchors = generateTiledAnchors(predictions,anchors,anchorBoxMasks,... anchorIndex); predictions = applyAnchorBoxOffsets(tiledAnchors, predictions,... networkInputSize, anchorIndex); [bboxes,scores,labelsIndex] = generateYOLOv3DetectionsForCodegen(predictions,... confidenceThreshold, overlapThreshold, imageSize, classes); end function YPredCell = yolov3Predict(matFile,im,networkOutputs,anchorBoxMask) % Predict the output of network and extract the confidence, x, y, % width, height, and class. % load the deep learning network for prediction persistent net; if isempty(net) net = coder.loadDeepLearningNetwork(matFile); end YPredictions = cell(coder.const(networkOutputs), 1); [YPredictions{:}] = predict(net, im); YPredCell = extractPredictions(YPredictions, anchorBoxMask); % Apply activation to the predicted cell array. YPredCell = applyActivations(YPredCell); end

评估物体检测的入口点函数

按照以下步骤来评估测试数据图像上的入口点函数。

  • 将置信阈值指定为0.5,以只保留置信评分高于此值的检测。

  • 指定重叠阈值为0.5,以消除重叠检测。

  • 从输入数据中读取图像。

  • 使用入口点功能yolov3Detect以获得预测的边界框、置信度得分和类标签。

  • 显示图像与边界框和信心分数。

定义所需的阈值。

信心阈值=0.5;重叠阈值=0.5;

指定训练网络的网络输入大小和网络输出数量。

networkInputSize = [227 227 3];networkOutputs =元素个数(net.OutputNames);

从标记数据集中读取示例图像数据使用YOLO v3深度学习的对象检测(计算机视觉工具箱)的例子。这个图像包含一个车辆类型的对象实例。

I=imread(“vehicleImage.jpg”);

指定类名。

一会= {“汽车”};

在YOLO v3网络上调用检测方法并显示结果。

[bboxes,分数,labelsIndex] = yolov3Detect (matFile,我,...networkInputSize、networkOutputs confidenceThreshold overlapThreshold,类名);标签=一会(labelsIndex);%在图像上显示检测结果IAnnotated = insertObjectAnnotation(我“矩形”、bboxes strcat(标签,{“- - -”}, num2str(分数)));图imshow (IAnnotated)

生成CUDA墨西哥人

生成CUDA®代码yolov3Detect为MEX目标创建一个GPU代码配置对象,并将目标语言设置为c++。使用编码器。DeepLearningConfig函数创建一个CuDNN深度学习配置对象,并将其分配给DeepLearningConfig图形处理器代码配置对象的属性。

cfg = coder.gpuConfig (墨西哥人的);cfg。TargetLang =“c++”;cfg。DeepLearningConfig =编码器。DeepLearningConfig(TargetLibrary=“cudnn”);args = {coder.Constant (matFile),我,coder.Constant (networkInputSize),...confidenceThreshold coder.Constant (networkOutputs),...overlapThreshold,一会};codegen配置cfgyolov3Detectarg游戏arg游戏报告
代码生成成功:查看报告

为TensorRT目标生成CUDA®代码,创建并使用TensorRT深度学习配置对象来代替CuDNN配置对象。同样,要为MKLDNN目标生成代码,需要创建一个CPU代码配置对象,并使用MKLDNN深度学习配置对象作为其DeepLearningConfig财产。

运行生成的MEX

使用相同的图像输入调用生成的CUDA MEX如前所述,显示结果。

[bboxes,分数,labelsIndex] = yolov3Detect_mex (matFile,我,...networkInputSize、networkOutputs confidenceThreshold,...overlapThreshold,类名);标签=一会(labelsIndex);图;IAnnotated = insertObjectAnnotation(我“矩形”、bboxes strcat(标签,{“- - -”}, num2str(分数)));imshow (IAnnotated);

效用函数

下面列出的实用程序函数是基于使用YOLO v3深度学习的对象检测(计算机视觉工具箱)示例并修改以使实用程序函数适合于代码生成。

类型(“applyActivations.m”
function YPredCell = applyActivations(YPredCell) %#codegen % Copyright 2020-2021 The MathWorks, Inc. numCells = size(YPredCell, 1);for iCell = 1:numCells for idx = 1:3 YPredCell{iCell,idx} = sigmoidActivation(YPredCell{iCell,idx});end end for iCell = 1:numCells for idx = 4:5 YPredCell{iCell, idx} = exp(YPredCell{iCell, idx});end end for iCell = 1:numCells YPredCell{iCell, 6} = sigmoidActivation(YPredCell{iCell, 6});end end function out = sigmoidActivation(x) out = 1 /(1+exp(-x));结束
类型(“extractPredictions.m”
function predictions = extractPredictions(YPredictions, anchorBoxMask) %#codegen % Copyright 2020-2021 The MathWorks, Inc. numPredictionHeads = size(YPredictions, 1);预测=细胞(numPredictionHeads 6);for ii = 1:numPredictionHeads %获取特性大小所需的信息。numChannelsPred =大小(YPredictions {2}, 3);numAnchors =大小(anchorBoxMask {2}, 2);numPredElemsPerAnchors = numChannelsPred / numAnchors;allIds = (1: numChannelsPred);步= numPredElemsPerAnchors;endIdx = numChannelsPred;YPredictionsData = extractdata (YPredictions {2}); % X positions. startIdx = 1; predictions{ii,2} = YPredictionsData(:,:,startIdx:stride:endIdx,:); xIds = startIdx:stride:endIdx; % Y positions. startIdx = 2; predictions{ii,3} = YPredictionsData(:,:,startIdx:stride:endIdx,:); yIds = startIdx:stride:endIdx; % Width. startIdx = 3; predictions{ii,4} = YPredictionsData(:,:,startIdx:stride:endIdx,:); wIds = startIdx:stride:endIdx; % Height. startIdx = 4; predictions{ii,5} = YPredictionsData(:,:,startIdx:stride:endIdx,:); hIds = startIdx:stride:endIdx; % Confidence scores. startIdx = 5; predictions{ii,1} = YPredictionsData(:,:,startIdx:stride:endIdx,:); confIds = startIdx:stride:endIdx; % Accumulate all the non-class indexes nonClassIds = [xIds yIds wIds hIds confIds]; % Class probabilities. % Get the indexes which do not belong to the nonClassIds classIdx = setdiff(allIds, nonClassIds, 'stable'); predictions{ii,6} = YPredictionsData(:,:,classIdx,:); end end
类型(“generateTiledAnchors.m”
函数tiledAnchors = generateTiledAnchors(YPredCell,锚盒,…%生成平铺锚偏移量,用于将预测从YOLO % v3网格单元坐标转换为边界框坐标%#codegen % Copyright 2020-2021 the MathWorks, Inc. numPredictionHeads = size(YPredCell,1);tiledAnchors = cell(numPredictionHeads, size(anchorIndex, 2));for i = 1:numPredictionHeads anchors =主播盒(主播盒掩码{i},:);[h, w ~ n] =大小(YPredCell{我1});[tiledAnchors{2},我tiledAnchors{1}我]= ndgrid (h - 0: 0: w1,…1:尺寸(锚,1),1:n);[~, ~, tiledAnchors{我3}]= ndgrid (h - 0: 0: w1,锚(:,2),1:n);[~, ~, tiledAnchors{我4}]= ndgrid (h - 0: 0: w1,锚(:1),1:n);结束结束
类型(“applyAnchorBoxOffsets.m”
function YPredCell = applyanchorboxoffset (tiledAnchors,YPredCell,…inputImageSize,anchorIndex) %#codegen % Convert the predictions from the YOLO v3 grid cell coordinates to % bounding box coordinates % Copyright 2020-2021 the MathWorks, Inc. for i = 1:size(YPredCell,1) [h,w,~,] = size(YPredCell{i,1});YPredCell{我anchorIndex (1)} = (tiledAnchors{1}我+……YPredCell{我anchorIndex(1)})。/ w;YPredCell{我anchorIndex (2)} = (tiledAnchors{我2}+……YPredCell{我anchorIndex (2)}) / h;YPredCell{我anchorIndex (3)} = (tiledAnchors{3}我。*……YPredCell{我anchorIndex(3)})。/ inputImageSize (2);YPredCell{我anchorIndex (4)} = (tiledAnchors{4}我。*……YPredCell{我anchorIndex(4)})。/ inputImageSize (1); end end
类型(“preprocessData.m”
函数图像=预处理数据(图像,targetSize)%s调整图像大小,并将像素缩放到0到1之间。%#codegen%版权所有2020-2021 The MathWorks,Inc.imgSize=尺寸(图像);%将具有单通道的输入图像转换为3个通道。如果numel(imgSize)<1图像=repmat(图像,1,1,3);结束图像=im2single(重新缩放(图像));image=iLetterBoxImage(图像,编码器常数(targetSize(1:2));结束函数Inew=iLetterBoxImage(I,targetSize)%LetterBoxImage通过保留输入图像I的宽度和高度%纵横比来返回调整大小的图像。“targetSize”是由%目标维度组成的1×2向量。%%输入I可以是uint8、uint16、int16、double、single或logical,并且必须是实的和非稀疏的。[Irow,Icol,Ichannels]=尺寸(I);%计算纵横比。arI=Irow./Icol;%根据纵横比保留最大尺寸。如果arI<1 IcolFin=targetSize(1,2);IrowFin=地板(IcolFin.*arI);else IrowFin=目标尺寸(1,1);IcolFin=地板(IrowFin./arI);结束%调整输入图像的大小。Itmp=imresize(I[IrowFin,IcolFin]);%使用灰色值初始化Inew。Inew=一([targetSize,Ichannels],'like',I)。*0.5;%计算偏移量。如果arI<1 buff=targetSize(1,1)-IrowFin;else buff=目标尺寸(1,2)-IcolFin;结束%将调整大小的图像放置在画布图像上。如果(buff==0)Inew=Itmp;else buffVal=地板(buff/2);如果arI<1 Inew(buffVal:buffVal+IrowFin-1,:,:)=Itmp;else Inew(:,buffVal:buffVal+IcolFin-1,:)=Itmp;结束

参考文献

1.雷德蒙,约瑟夫和阿里·法哈迪。“YOLOv3:一个渐进的改进。”预印本,2018年4月8日提交。https://arxiv.org/abs/1804.02767。

另请参阅

功能

对象

相关的例子

更多关于