В этом примере показано, как использовать codegen команда для создания кода для приложения классификации изображений, использующего глубокое изучение процессоров Intel ®. Созданный код использует библиотеку Intel Math Kernel Library for Deep Neural Networks (MKL-DNN). Этот пример состоит из двух частей:
В первой части показано, как создать функцию MEX, которая принимает пакет изображений в качестве входных данных.
Во второй части показано, как создать исполняемый файл, который принимает пакет изображений в качестве входных данных.
Процессор Intel с поддержкой команд Intel Advanced Vector Extensions 2 (Intel AVX2)
Библиотека Intel Math Kernel Library для глубоких нейронных сетей (MKL-DNN)
Переменные среды для компиляторов и библиотек. Сведения о поддерживаемых версиях компиляторов см. в разделе Поддерживаемые компиляторы. Сведения о настройке переменных среды см. в разделе Предпосылки для глубокого обучения с помощью кодера MATLAB (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.
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. Поскольку параметр batchSize имеет значение 5 read 5 images. Увеличьте размер пакета входных изображений до размера, требуемого по размеру resnet50, ожидаемому сетью 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++ и использование вместо нее созданного примера C++ не планируется, установите 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')