主要内容

针对不同批量大小的Intel目标的深度学习代码生成

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

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

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

先决条件

该示例支持Linux®,Windows®和Mac®平台,不支持MATLAB Online。

下载输入视频文件

下载一个示例视频文件。

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

定义resnet_predict函数

这个示例使用DAG网络ResNet-50在Intel桌面显示图像分类。一个预训练的MATLAB ResNet-50模型是支持包ResNet-50网络深度学习工具箱模型的一部分。

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

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

生成MEXresnet_predict

来生成MEX函数resnet_predict功能,使用codegen使用MKL-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读取函数读取5帧。由于batchSize设置为5读取5个图像。调整批量输入图像的大小为resnet50所需的大小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), '下行');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 = {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, [scl, srow], 'Classification with ResNet-50', 'TextColor', 'w','FontSize',20, 'BoxColor', 'black');麻雀=麻雀+ 30;for k = 1:5 outputImage = insertText(outputImage, [scl, srow], [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用于加载系列网络对象。第一次调用此函数时,将构造持久对象并设置。当该函数随后被调用时,将重用相同的对象%来调用输入上的predict,避免重构和重新加载% network对象。持久mynet;调用函数resnet50,返回ResNet-50模型的DAG网络%。mynet = code . loaddeeplearningnetwork ('resnet50','resnet');end %创建视频阅读器和视频播放器对象% 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作为输入参数。它读取分类标签并填充单元格数组。

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

readImageInputBatch函数

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

根据输入参数% % % %输入:% videoReader -用于从视频文件中读取图像的对象% batchSize -批量处理的图像数量。由用户% i - index提供,用于从视频文件% %读取的跟踪帧。输出:% reSizedImagesBatch -批量调整为224x224x3xbatchsize的图像
img = read(videoReader,[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函数

该函数接受预测结果并按降序排序。它将这些结果覆盖到输入图像上并显示它们。

% % %输入:% predict_scores -给定网络的分类结果% synsetOut -单元格数组中填充了1000个图像类标签% reSizedImagesBatch -将图像调整为224x224x3xbatchsize % batchSize -批量处理的图像数量。由用户% depVideoPlayer -显示结果的对象% %输出:%预测结果覆盖在输入图像上
% sort预测分数% [val,indx] = sort(转置(predict_scores), '下行');
for j = 1:batchSize scores = val(1:5,j)*100;outputImage = 0 (224,400,3, 'uint8');outputImage(:,177:end,k) = reSizedImagesBatch(:,:,k,j);结束
将结果叠加在图像上% sool = 1;麻雀= 1;outputImage = insertText(outputImage, [scol, srow], 'Classification with ResNet-50', 'TextColor', [255 255 255],'FontSize',20, 'BoxColor', [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]);麻雀=麻雀+ 25;结束
depVideoPlayer (outputImage);结束结束

构建并运行可执行文件

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

如果您不打算创建自定义c++ main函数,而是使用生成的示例c++ main,请将GenerateExampleMain参数“GenerateCodeAndCompile”。另外,禁用cfg。EnableOpenMP以确保从桌面终端运行可执行文件时不存在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)} -报告系统('./resnet_predict_exe')

另请参阅

|||

相关的话题

Baidu
map