В этом примере показано, как использовать codegen команда для генерации кода для приложения классификации изображений, использующего глубокое обучение на процессорах Intel ®. Сгенерированный код использует Math Kernel Library для глубоких нейронных сетей (MKL-DNN). Этот пример состоит из двух частей:
В первой части показано, как сгенерировать MEX-функцию, которая принимает пакет изображений как вход.
Вторая часть показывает, как сгенерировать исполняемый файл, который принимает пакет изображений как вход.
Процессор Intel с поддержкой инструкций Intel Advanced Vector Extensions 2 (Intel AVX2)
Intel Math Kernel Library для глубоких нейронных сетей (MKL-DNN)
Переменные окружения для компиляторов и библиотек. Дополнительные сведения о поддерживаемых версиях компиляторов см. в разделе Поддерживаемые компиляторы. Для настройки переменных окружения смотрите Необходимые условия глубокого обучения с MATLAB Coder (MATLAB Coder).
Этот пример поддерживается на платформах Linux ®, Windows ® и Mac ® и не поддерживается для MATLAB Online.
Загрузите выборку видео файла.
if ~exist('./object_class.avi', 'file')
url = 'https://www.mathworks.com/supportfiles/gpucoder/media/object_class.avi.zip';
websave('object_class.avi.zip',url);
unzip('object_class.avi.zip');
endresnet_predict ФункцияЭтот пример использует сетевую ResNet-50 DAG, чтобы показать классификацию изображений на рабочих столах Intel. Предварительно обученная модель ResNet-50 для MATLAB доступна в рамках пакета поддержки Deep Learning Toolbox Model for ResNet-50 Network.
The resnet_predict функция загружает ResNet-50 сеть в объект постоянной сети, а затем выполняет предсказание на входе. Последующие вызовы функции повторно используют объект постоянной сети.
type resnet_predict
% Copyright 2020 The MathWorks, Inc.
function out = resnet_predict(in)
%#codegen
% A persistent object mynet is used to load the series network object.
% At the first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is reused
% to call predict on inputs, avoiding reconstructing and reloading the
% network object.
persistent mynet;
if isempty(mynet)
% Call the function resnet50 that returns a DAG network
% for ResNet-50 model.
mynet = coder.loadDeepLearningNetwork('resnet50','resnet');
end
% pass in input
out = mynet.predict(in);
resnet_predictЧтобы сгенерировать MEX-функцию для resnet_predict функция, использование codegen с объектом строения глубокого обучения для библиотеки MKL-DNN. Присоедините объект строения глубокого обучения к объекту строения генерации кода MEX, которому вы передаете codegen. Запуск codegen и задайте вход как 4D матрицу размера [224,224,3,|batchSize|]. Это значение соответствует размеру входного слоя ResNet-50 сети.
batchSize = 5;
cfg = coder.config('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('mkldnn');
codegen -config cfg resnet_predict -args {ones(224,224,3,batchSize,'single')} -report
Code generation successful: To view the report, open('codegen\mex\resnet_predict\html\report.mldatx').
Предполагая, что Object_class.avi видео файла уже загружено. Создайте объект videoReader и прочитайте пять систем координат с помощью функции videoReader read. Поскольку значение batchSize установлено равным 5, считайте 5 изображений. Измените размер пакета входа изображений до размера, необходимого для сброса размера 50, ожидаемого ResNet50 сети.
videoReader = VideoReader('Object_class.avi');
imBatch = read(videoReader,[1 5]);
imBatch = imresize(imBatch, [224,224]);Вызовите сгенерированный resnet_predict_mex функция, которая выводит результаты классификации для входов, которые вы предоставляете.
predict_scores = resnet_predict_mex(single(imBatch));
Получите 5 лучшие счета вероятностей и их меток для каждого изображения в пакете.
[val,indx] = sort(transpose(predict_scores), 'descend');
scores = val(1:5,:)*100;
net = resnet50;
classnames = net.Layers(end).ClassNames;
for i = 1:batchSize
labels = classnames(indx(1:5,i));
disp(['Top 5 predictions on image, ', num2str(i)]);
for j=1:5
disp([labels{j},' ',num2str(scores(j,i), '%2.2f'),'%'])
end
endДля предсказаний на первом изображении сопоставьте пять лучших счетов предсказания со словами в synset словарь.
fid = fopen('synsetWords.txt');
synsetOut = textscan(fid,'%s', 'delimiter', '\n');
synsetOut = synsetOut{1};
fclose(fid);
[val,indx] = sort(transpose(predict_scores), 'descend');
scores = val(1:5,1)*100;
top5labels = synsetOut(indx(1:5,1));Отобразите пять лучших классификационных меток на изображении.
outputImage = zeros(224,400,3, 'uint8');
for k = 1:3
outputImage(:,177:end,k) = imBatch(:,:,k,1);
end scol = 1;
srow = 1;
outputImage = insertText(outputImage, [scol, srow], 'Classification with ResNet-50', 'TextColor', 'w','FontSize',20, 'BoxColor', 'black');
srow = srow + 30;
for k = 1:5
outputImage = insertText(outputImage, [scol, srow], [top5labels{k},' ',num2str(scores(k), '%2.2f'),'%'], 'TextColor', 'w','FontSize',15, 'BoxColor', 'black');
srow = srow + 25;
endimshow(outputImage);

Очистить сохраняющийся сетевой объект из памяти.
clear mex;
resnet_predict_exe Функция точки входаЧтобы сгенерировать исполняемый файл из кода MATLAB, задайте новую функцию точки входа resnet_predict_exe. Эта функция аналогична предыдущей функции точки входа resent_predict но, в сложение, включает код для предварительной обработки и постобработки. API, который resnet_predict_exe использование не зависит от платформы. Эта функция принимает видео и размер пакета как входные параметры. Эти аргументы являются константами во время компиляции.
type resnet_predict_exe
% Copyright 2020 The MathWorks, Inc.
function resnet_predict_exe(inputVideo,batchSize)
%#codegen
% A persistent object mynet is used to load the series network object.
% At the first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is reused
% to call predict on inputs, avoiding reconstructing and reloading the
% network object.
persistent mynet;
if isempty(mynet)
% Call the function resnet50 that returns a DAG network
% for ResNet-50 model.
mynet = coder.loadDeepLearningNetwork('resnet50','resnet');
end
% Create video reader and video player objects %
videoReader = VideoReader(inputVideo);
depVideoPlayer = vision.DeployableVideoPlayer;
% Read the classification label names %
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.txt файл как входной параметр. Он считывает метки классификации и заполняет массив ячеек.
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);
endreadImageInputBatch ФункцияЭта функция считывает и изменяет размер изображений из входа файла видео, который передается в функцию как входной параметр. Он считывает указанные входные изображения и изменяет их размер до 224x224x3, который является размером, ожидаемым сетью resnet50.
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);
endmynet.predict ФункцияЭта функция принимает измененный размер пакета изображений как вход и возвращает результаты предсказания.
% run predict on resized input images %
predict_scores = mynet.predict(reSizedImagesBatch);overlayResultsOnImages ФункцияЭта функция принимает результаты предсказания и сортирует их в порядке убывания. Он накладывает эти результаты на входные изображения и отображает их.
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Создайте объект строения кода для генерации исполняемого файла. Прикрепите к нему объект строения глубокого обучения. Установите batchSize и inputVideoFile переменные.
Если вы не намерены создавать пользовательскую функцию C++ main и вместо этого используете сгенерированный пример C++ main, установите GenerateExampleMain параметр в 'GenerateCodeAndCompile'. Также отключите cfg. EnableOpenMP, чтобы убедиться, что нет никаких библиотечных зависимостей openmp, когда вы запускаете свой исполняемый файл с рабочего стола.
cfg = coder.config('exe');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('mkldnn');
batchSize = 5;
inputVideoFile = 'object_class.avi';
cfg.GenerateExampleMain = 'GenerateCodeAndCompile';
cfg.EnableOpenMP = 0;Запуск codegen команда для создания исполняемого файла. Запустите сгенерированный исполняемый resnet_predict_exe либо в командной строке MATLAB, либо на настольном терминале.
codegen -config cfg resnet_predict_exe -args {coder.Constant(inputVideoFile), coder.Constant(batchSize)} -report
system('./resnet_predict_exe')