主要内容

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

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

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

预先训练的YOLO v3网络

本示例使用Yolov3squezenetvehicle示例_21a.zip包含预训练的YOLO v3网络的文件。该文件大小约为9MB。请从MathWorks网站下载该文件,然后解压缩该文件。

fileName=matlab.internal.examples.downloadSu万博1manbetxpportFile(“愿景/数据/”,“yolov3SqueezeNetVehicleExample_21a.zip”);解压缩(文件名);

本例中使用的YOLO v3网络使用中描述的步骤进行培训基于YOLO v3深度学习的目标检测(计算机视觉工具箱).

matFile =“Yolov3squezenetvehicleeexample_21a.mat”;预训练=加载(matFile);net=预训练.net;

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

注:您还可以通过YOLO v3对象检测支持包的计算机视觉工具箱™模型使用预先训练过的检测器网络。万博1manbetx

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

然后,保存网络从yolov3ObjectDetector对象到MAT文件并继续。例如,

检测器=yolov3ObjectDetector(“黑色53可可”);网= detector.Network;matFile =“pretrainedYOLOv3Detector.mat”;保存(matFile,“净”);

这个yolov3Detect入口点函数

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

类型(“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以获得预测的边界框、置信度得分和类标签。

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

定义所需的阈值。

confidenceThreshold = 0.5;overlapThreshold = 0.5;

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

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

从标记数据集中读取示例图像数据基于YOLO v3深度学习的目标检测(计算机视觉工具箱)示例。此图像包含类型为vehicle的对象的一个实例。

我= 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=coder.DeepLearningConfig(TargetLibrary=“cudnn”);args={coder.Constant(matFile),I,coder.Constant(networkInputSize),...编码器常数(网络输出),置信阈值,...overlapThreshold,一会};编码基因-配置cfgyolov3Detect-argsarg游戏报告
代码生成成功:查看报告

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

运行生成的MEX

使用相同的图像输入调用生成的CUDA MEX并显示结果。

[b框、分数、标签索引]=yolov3Detect_mex(matFile,I,...networkInputSize、networkOutputs confidenceThreshold,...重叠阈值,类名);标签=类名(labelsIndex);图;IANotated=insertObjectAnnotation(I,“矩形”、bboxes strcat(标签,{“- - -”}, num2str(分数)));imshow (IAnnotated);

效用函数

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

类型(“applyActivations.m”)
函数YPredCell=applyActivations(YPredCell)%#codegen%版权所有2020-2021 MathWorks,Inc.numCells=size(YPredCell,1);对于iCell=1:idx的numCells=1:3 YPredCell{iCell,idx}=sigmoidActivation(YPredCell{iCell,idx});iCell=1的结束端:idx=4:5的numCells{iCell,idx}=exp(YPredCell{,idx});iCell的end-end=1:numCells-YPredCell{iCell,6}=sigmoidActivation(YPredCell{iCell,6});end-end函数out=sigmoidActivation(x)out=1./(1+exp(-x));end
类型(“是的,我是”)
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”)
函数平铺锚=生成锚(YPredCell,AnchorBox,…AnchorBox Mask,anchorIndex)%生成平铺锚偏移,用于将预测从YLO%v3网格单元坐标转换为边界框坐标%#codegen%版权所有2020-2021 MathWorks,Inc.numPredictionHeads=大小(YPredCell,1);平铺锚=单元(Nump预测头,尺寸(anchorIndex,2));i=1:i=i=1:Nu预测头锚锚=锚盒(Ancho预测头锚=锚盒(AnchoorboxMask{i},:;;[h,w,w,w,,,[h,w,w,n]=尺寸(ypRed预测头,尺寸)(ypRed预测头,大小,尺寸(ypRedRedCe层细胞{{i,1,1,1});;;;;;;;;[h,w,w,w,w,w,w,,,,,,,[n]=尺寸(尺寸)尺寸(ypRedRedRedCe,(ypRed单元格,尺寸,尺寸(ypRedCeCeCeCeCeCeCe层细胞,尺寸,尺寸(ypRed细胞{......1,1,1,1,1,1});;;;;;;;;;;;;;;;;;;;;;;;;;;;}]=ndgrid(0:h-1,0:w-1,锚固件(:,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”)
调整图像的大小,并将像素缩放到0到1之间。%#codegen % Copyright 2020-2021 The MathWorks, Inc. imgSize = size(image);将单通道输入图像转换为3通道。if numel(imgSize) < 1 image = repmat(image,1,1,3); / /显示图片结束图像= im2single(rescale(image));形象= iLetterBoxImage(形象,coder.const (targetSize (1:2)));LetterBoxImage返回一个调整大小的图像,保留输入图像I的宽度和高度%纵横比。'targetSize'是一个1乘2的矢量,包含目标维度的%。% %输入I可以是uint8, uint16, int16, double, single, or logical,并且必须%是真实的和非稀疏的。[Irow, Icol Ichannels] =大小(我); % Compute aspect Ratio. arI = Irow./Icol; % Preserve the maximum dimension based on the aspect ratio. if arI<1 IcolFin = targetSize(1,2); IrowFin = floor(IcolFin.*arI); else IrowFin = targetSize(1,1); IcolFin = floor(IrowFin./arI); end % Resize the input image. Itmp = imresize(I,[IrowFin,IcolFin]); % Initialize Inew with gray values. Inew = ones([targetSize,Ichannels],'like',I).*0.5; % Compute the offset. if arI<1 buff = targetSize(1,1)-IrowFin; else buff = targetSize(1,2)-IcolFin; end % Place the resized image on the canvas image. if (buff==0) Inew = Itmp; else buffVal = floor(buff/2); if arI<1 Inew(buffVal:buffVal+IrowFin-1,:,:) = Itmp; else Inew(:,buffVal:buffVal+IcolFin-1,:) = Itmp; end end end

参考文献

1.Redmon、Joseph和Ali Farhadi.《约洛夫3:渐进式改进》,预印本,2018年4月8日提交。https://arxiv.org/abs/1804.02767.

另请参阅

功能

对象

相关实例

更多关于