为使用 YOLO v2 的目标检测生成代码
此示例说明如何为 you only look once (YOLO) v2 目标检测器生成 CUDA® MEX。YOLO v2 目标检测网络由两个子网络组成。一个特征提取网络,后跟一个检测网络。此示例为 Computer Vision Toolbox™ 的使用 YOLO v2 深度学习进行目标检测示例中训练的网络生成代码。有关详细信息,请参阅Object Detection Using YOLO v2 Deep Learning (Computer Vision Toolbox)。您可以修改此示例,以便为从 Computer Vision Toolbox™ 中的导入预训练 ONNX YOLO v2 目标检测器示例导入的网络生成 CUDA® MEX。有关详细信息,请参阅Import Pretrained ONNX YOLO v2 Object Detector (Computer Vision Toolbox)。
第三方前提条件
必需
此示例生成 CUDA MEX,并具有以下第三方要求。
CUDA® 支持 NVIDIA® GPU 和兼容驱动程序。
可选
对于非 MEX 编译,如静态、动态库或可执行文件,此示例有以下附加要求。
NVIDIA 工具包。
NVIDIA cuDNN 库。
编译器和库的环境变量。有关详细信息,请参阅Third-Party Hardware (GPU Coder)和Setting Up the Prerequisite Products (GPU Coder)。
验证 GPU 环境
使用 coder.checkGpuInstall
(GPU Coder) 函数验证运行此示例所需的编译器和库是否已正确设置。
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
获取预训练的 DAGNetwork
此示例使用包含预训练网络的 yolov2ResNet50VehicleExample
MAT 文件。文件大小约为 98MB。从 MathWorks® 网站下载该文件。
matFile = matlab.internal.examples.downloadSupportFile('vision/data','yolov2ResNet50VehicleExample.mat'); vehicleDetector = load(matFile); net = vehicleDetector.detector.Network
net = DAGNetwork with properties: Layers: [150×1 nnet.cnn.layer.Layer] Connections: [162×2 table] InputNames: {'input_1'} OutputNames: {'yolov2OutputLayer'}
DAG 网络包含 150 层,包括卷积层、ReLU 层和批量归一化层,以及 YOLO v2 变换层和 YOLO v2 输出层。要以交互可视方式呈现深度学习网络架构,请使用 analyzeNetwork
函数。
analyzeNetwork(net);
yolov2_detect
入口函数
yolov2_detect.m
入口函数以图像作为输入,并使用保存在 yolov2ResNet50VehicleExample.mat
文件中的深度学习网络对图像运行检测器。该函数将 yolov2ResNet50VehicleExample.mat
文件中的网络对象加载到持久变量 yolov2Obj 中,并在后续的检测调用中重用该持久性对象。
type('yolov2_detect.m')
function outImg = yolov2_detect(in,matFile) % Copyright 2018-2021 The MathWorks, Inc. persistent yolov2Obj; if isempty(yolov2Obj) yolov2Obj = coder.loadDeepLearningNetwork(matFile); end % Call to detect method [bboxes,~,labels] = yolov2Obj.detect(in,'Threshold',0.5); % Convert categorical labels to cell array of charactor vectors labels = cellstr(labels); % Annotate detections in the image. outImg = insertObjectAnnotation(in,'rectangle',bboxes,labels);
运行 MEX 代码生成
要为入口函数生成 CUDA 代码,请为 MEX 目标创建一个 GPU 代码配置对象,并将目标语言设置为 C++。使用 coder.DeepLearningConfig
(GPU Coder) 函数创建一个 CuDNN
深度学习配置对象,并将其赋给 GPU 代码配置对象的 DeepLearningConfig
属性。运行 codegen
命令,指定 224×224×3 输入大小。该值对应于 YOLOv2 的输入层大小。
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); cfg.GenerateReport = true; inputArgs = {ones(224,224,3,'uint8'),coder.Constant(matFile)}; codegen -config cfg yolov2_detect -args inputArgs
Code generation successful: View report
运行生成的 MEX
设置视频文件读取器并读取输入视频。创建视频播放器来显示视频和输出检测。
videoFile = 'highway_lanechange.mp4'; videoFreader = VideoReader(videoFile); depVideoPlayer = vision.DeployableVideoPlayer('Size','Custom','CustomSize',[640 480]);
逐帧读取视频输入,并使用检测器检测视频中的车辆。
while hasFrame(videoFreader) I = readFrame(videoFreader); in = imresize(I,[224,224]); out = yolov2_detect_mex(in,matFile); depVideoPlayer(out); % Exit the loop if the video player figure window is closed cont = hasFrame(videoFreader) && isOpen(depVideoPlayer); end
参考资料
[1] Redmon, Joseph, and Ali Farhadi."YOLO9000:Better, Faster, Stronger."2017 IEEE Conference on Computer Vision and Pattern Recognition (CVPR).IEEE, 2017.