主要内容

基于Intel目标的不同批处理大小的深度学习代码生成

方法的使用codegen命令为在英特尔®处理器上使用深度学习的图像分类应用程序生成代码。生成的代码使用英特尔深度神经网络数学内核库(MKL-DNN)。本例由两部分组成:

  • 第一部分展示了如何生成一个接受一批图像作为输入的MEX函数。

  • 第二部分展示了如何生成一个可执行文件,该文件接受一批图像作为输入。

先决条件

此示例支持Linux®,Wind金宝appows®和Mac®平台,不支持MATLAB Online。

下载输入视频文件

下载一个示例视频文件。

如果~存在(“。/ object_class。Avi ', 'file') url = '//www.tatmou.com金宝app/supportfiles/gpucoder/media/object_class.avi.zip';websave (object_class.avi.zip, url);解压缩(“object_class.avi.zip”);结束

定义resnet_predict函数

本例使用DAG网络ResNet-50在Intel台式机上显示图像分类。一个预先训练的ResNet-50 MATLAB模型可作为支持包ResNet-50网络深度学习工具箱模型的一部分。金宝app

resnet_predict函数将ResNet-50网络加载到一个持久网络对象中,然后对输入进行预测。对该函数的后续调用重用持久网络对象。

类型resnet_predict
MathWorks, Inc.函数out = resnet_predict(in) %#codegen %一个持久化对象mynet用于加载系列网络对象。在第一次调用此函数时,将构造持久对象,并且% setup。在以后多次调用该函数时,将重用相同的对象%,以对输入调用predict,从而避免重构和重新加载% network对象。持久mynet;调用函数resnet50,返回ResNet-50模型的DAG网络%。mynet = code . loaddeeplearningnetwork ('resnet50','resnet');输入输出= mynet.predict(in);

resnet_predict

为对象生成MEX函数resnet_predict功能,使用codegen带有mml - dnn库的深度学习配置对象。将深度学习配置对象附加到要传递给的MEX代码生成配置对象codegen.运行codegen命令,并指定输入为大小为[224,224,3,|batchSize|]的4D矩阵。该值对应ResNet-50网络的输入层大小。

batchSize = 5;CFG = code .config(墨西哥人的);cfg。TargetLang =“c++”;cfg。DeepLearningConfig =编码器。DeepLearningConfig (“mkldnn”);codegen配置cfgresnet_predictarg游戏{的(224224 3 batchSize '单')}报告
要查看报告,请打开('codegen\mex\resnet_predict\html\report.mldatx')。

对一批图像进行预测

假设object_类。Avi视频文件已经下载。创建videoReader对象并使用videoReader read函数读取5帧。由于batchSize设置为5读取5个图像,因此将输入图像的批量大小调整为resnet50网络所需的大小。

videoReader = videoReader ('Object_class.avi');imBatch = read(videereader,[1 5]);imBatch = imresize(imBatch, [224,224]);

调用生成的resnet_predict_mex函数,该函数输出您提供的输入的分类结果。

predict_scores = resnet_predict_mex(single(imBatch));

获得前5个概率分数和他们的标签为每批图像。

[val,indx] = sort(转置(predict_scores), '下降');分数= val(1:5,:)*100;Net = resnet50;classnames = net.Layers(end).ClassNames;for i = 1:batchSize标签= classnames(indx(1:5,i));disp(['图像上的前5个预测,',num2str(i)]);j = 1:5 disp([标签{j},“num2str(分数(j,我),% 2.2 f), ' % '])结束

对于第一个图像上的预测,将前五个预测分数映射到同义词集字典。

fid = fopen('synsetWords.txt');synsetOut = textscan(fid,'%s', '分隔符','\n');synsetOut = synsetOut{1};文件关闭(fid);[val,indx] = sort(转置(predict_scores), '下降');分数= val(1:5,1)*100;top5labels = synsetOut(indx(1:5,1));

显示图像上排名前五的分类标签。

outputImage = 0 (224,400,3, 'uint8');outputImage(:,177:end,k) = imBatch(:,:,k,1);结束
Scol = 1;麻雀= 1;outputImage = insertText(outputImage, [scol, srow], '分类与ResNet-50', 'TextColor', 'w','FontSize',20, 'BoxColor', '黑色');麻雀=麻雀+ 30;for k = 1:5 outputImage = insertText(outputImage, [scol, row], [top5labels{k},' ',num2str(scores(k), '%2.2f'),'%'], 'TextColor', 'w','FontSize',15, 'BoxColor', 'black');麻雀=麻雀+ 25;结束
imshow (outputImage);

从内存中清除持久网络对象。

清晰的墨西哥人

定义resnet_predict_exe入口点函数

为了从MATLAB代码生成可执行文件,定义一个新的入口点函数resnet_predict_exe.这个函数类似于前面的入口点函数resent_predict但是,除此之外,还包括用于预处理和后处理的代码。这个APIresnet_predict_exeUses是平台独立的。这个函数接受视频和批处理大小作为输入参数。这些参数是编译时常量。

类型resnet_predict_exe
MathWorks, Inc.函数resnet_predict_exe(inputVideo,batchSize) %#codegen %一个持久对象mynet用于加载系列网络对象。在第一次调用此函数时,将构造持久对象,并且% setup。在以后多次调用该函数时,将重用相同的对象%,以对输入调用predict,从而避免重构和重新加载% network对象。持久mynet;调用函数resnet50,返回ResNet-50模型的DAG网络%。mynet = code . loaddeeplearningnetwork ('resnet50','resnet');创建视频阅读器和视频播放器对象% videoReader = videoReader (inputVideo);depVideoPlayer = vision.DeployableVideoPlayer;%读取分类标签名称% synsetOut = readImageClassLabels('synsetWords.txt');i = 1; % Read frames until end of video file % while ~(i+batchSize > (videoReader.NumFrames+1)) % Read and resize batch of frames as specified by input argument% reSizedImagesBatch = readImageInputBatch(videoReader,batchSize,i); % run predict on resized input images % predict_scores = mynet.predict(reSizedImagesBatch); % overlay the prediction scores on images and display % overlayResultsOnImages(predict_scores,synsetOut,reSizedImagesBatch,batchSize,depVideoPlayer) i = i+ batchSize; end release(depVideoPlayer); end function synsetOut = readImageClassLabels(classLabelsFile) % Read the classification label names from the file % % Inputs : % classLabelsFile - supplied by user % % Outputs : % synsetOut - cell array filled with 1000 image class labels synsetOut = cell(1000,1); fid = fopen(classLabelsFile); for i = 1:1000 synsetOut{i} = fgetl(fid); end fclose(fid); end function reSizedImagesBatch = readImageInputBatch(videoReader,batchSize,i) % Read and resize batch of frames as specified by input argument% % % Inputs : % videoReader - Object used for reading the images from video file % batchSize - Number of images in batch to process. Supplied by user % i - index to track frames read from video file % % Outputs : % reSizedImagesBatch - Batch of images resized to 224x224x3xbatchsize img = read(videoReader,[i (i+batchSize-1)]); reSizedImagesBatch = coder.nullcopy(ones(224,224,3,batchSize,'like',img)); resizeTo = coder.const([224,224]); reSizedImagesBatch(:,:,:,:) = imresize(img,resizeTo); end function overlayResultsOnImages(predict_scores,synsetOut,reSizedImagesBatch,batchSize,depVideoPlayer) % Read and resize batch of frames as specified by input argument% % % Inputs : % predict_scores - classification results for given network % synsetOut - cell array filled with 1000 image class labels % reSizedImagesBatch - Batch of images resized to 224x224x3xbatchsize % batchSize - Number of images in batch to process. Supplied by user % depVideoPlayer - Object for displaying results % % Outputs : % Predicted results overlayed on input images % sort the predicted scores % [val,indx] = sort(transpose(predict_scores), 'descend'); for j = 1:batchSize scores = val(1:5,j)*100; outputImage = zeros(224,400,3, 'uint8'); for k = 1:3 outputImage(:,177:end,k) = reSizedImagesBatch(:,:,k,j); end % Overlay the results on image % scol = 1; srow = 1; outputImage = insertText(outputImage, [scol, srow], 'Classification with ResNet-50', 'TextColor', [255 255 255],'FontSize',20, 'BoxColor', [0 0 0]); srow = srow + 30; for k = 1:5 scoreStr = sprintf('%2.2f',scores(k)); outputImage = insertText(outputImage, [scol, srow], [synsetOut{indx(k,j)},' ',scoreStr,'%'], 'TextColor', [255 255 255],'FontSize',15, 'BoxColor', [0 0 0]); srow = srow + 25; end depVideoPlayer(outputImage); end end

的结构resnet_predict_exe函数

这个函数resnet_predict_exe包含执行这些操作的四个子部分:

  • 从提供的输入文本文件中读取分类标签

  • 读取输入批图像并根据网络需要调整它们的大小

  • 对输入图像批处理运行推理

  • 将结果叠加在图像上

有关这些步骤的更多信息,请参阅后续部分。

readImageClassLabels函数

此函数接受synsetWords.txtFile作为输入参数。它读取分类标签并填充单元格数组。

function synsetOut = readImageClassLabels(classLabelsFile) %从文件中读取分类标签名称% %输入:% classLabelsFile -由用户提供% %输出:% synsetOut -填充1000个图像类标签的单元格数组
synsetOut = cell(1000,1);fid = fopen(classLabelsFile);for i = 1:1000 synsetOut{i} = fgetl(fid);最终文件关闭(fid);结束

readImageInputBatch函数

这个函数从作为输入参数传递给函数的视频输入文件中读取图像并调整图像的大小。它读取指定的输入图像并将其大小调整为224x224x3,这是resnet50网络期望的大小。

function reSizedImagesBatch = readImageInputBatch(videoReader,batchSize,i) %根据输入参数指定读取和调整批量帧的大小% % % input: % videoReader -用于从视频文件中读取图像的对象% batchSize -批量处理的图像数量。由用户% i提供- index从视频文件中读取的跟踪帧% %输出:% reSizedImagesBatch -将图像大小调整为224x224x3xbatchsize
img = read(视频读取器,[i (i+batchSize-1)]);reSizedImagesBatch = code .nullcopy(ones(224,224,3,batchSize,'like',img));resizeTo = code .const([224,224]);reSizedImagesBatch(:,:,:,:) = imresize(img,resizeTo);结束

mynet.predict函数

该函数接受调整大小的批图像作为输入,并返回预测结果。

% predict_scores = mynet.predict(reSizedImagesBatch);

overlayResultsOnImages函数

该函数接受预测结果,并按降序进行排序。它将这些结果叠加在输入图像上并显示出来。

function overlayResultsOnImages(predict_scores,synsetOut,reSizedImagesBatch,batchSize,depVideoPlayer) %根据输入参数读取和调整批量帧的大小% % %输入:% predict_scores -给定网络的分类结果% synsetOut -填充1000个图像类标签的单元格数组% reSizedImagesBatch -调整为224x224x3xbatchsize的批量图像% batchSize -批处理的图像数量。由用户% depVideoPlayer提供-用于显示结果% % Outputs: %预测结果叠加在输入图像上
% [val,indx] = sort(转置(predict_scores), '下降');
= val(1:5,j)*100;outputImage = 0 (224,400,3, 'uint8');outputImage(:,177:end,k) = reSizedImagesBatch(:,:,k,j);结束
将结果覆盖在图像上% scol = 1;麻雀= 1;outputImage = insertText(outputImage, [scol, srow], '分类与ResNet-50', 'TextColor', [255 255 255],'FontSize',20, 'BoxColor', [0 0 0 0]);麻雀=麻雀+ 30;scoreStr = sprintf('%2.2f',scores(k));outputImage = insertText(outputImage, [scol, srow], [synsetOut{indx(k,j)},' ',scoreStr,'%'], 'TextColor', [255 255 255],'FontSize',15, 'BoxColor', [0 0 0 0]);麻雀=麻雀+ 25;结束
depVideoPlayer (outputImage);结束结束

生成和运行可执行文件

创建用于生成可执行文件的代码配置对象。给它附加一个深度学习配置对象。设置batchSize而且inputVideoFile变量。

如果您不打算创建自定义c++ main函数,而是使用生成的示例c++ main,请设置GenerateExampleMain参数“GenerateCodeAndCompile”.另外,禁用cfg。启用openmp以确保从桌面终端运行可执行文件时没有openmp库依赖项。

CFG = code .config('exe');cfg。TargetLang = ' c++ ';cfg。DeepLearningConfig = code .DeepLearningConfig('mkldnn');batchSize = 5;inputVideoFile = 'object_class.avi';cfg。GenerateExampleMain = 'GenerateCodeAndCompile';cfg。EnableOpenMP = 0;

运行codegen命令构建可执行文件。在MATLAB命令行或桌面终端上运行生成的可执行程序resnet_predict_exe。

codegen -config cfg resnet_predict_exe -args {code . constant (inputVideoFile), code . constant (batchSize)} -report system('./resnet_predict_exe')

相关的话题