В этом примере показано, как использовать codegen
команда, чтобы сгенерировать код для приложения классификации изображений, которое использует глубокое обучение на процессорах Intel®. Сгенерированный код использует Math Kernel Library Intel для Глубоких нейронных сетей (MKL-DNN). Этот пример состоит из двух частей:
Первая часть показывает, как сгенерировать MEX-функцию, которая принимает пакет изображений, как введено.
Вторая часть показывает, как сгенерировать исполняемый файл, который принимает пакет изображений, как введено.
Процессор Intel с поддержкой Intel Усовершенствованные Векторные Расширения 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'); end
resnet_predict
ФункцияЭтот пример использует сеть DAG ResNet-50, чтобы показать классификацию изображений на рабочих столах Intel. Предварительно обученная модель ResNet-50 для MATLAB доступна как часть пакета поддержки Модель Deep Learning Toolbox для Сети ResNet-50.
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, function.Since batchSize чтения установлен в 5, читает 5 изображений.Resize пакет входных изображений к размеру, необходимому 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; end
imshow(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); end
readImageInputBatch
ФункцияЭта функция читает и изменяет размер изображений из файла ввода видео, который передается функции как входной параметр. Это читает заданные входные изображения и изменяет размер их к 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); end
mynet.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
Создайте объект настройки кода для генерации исполняемого файла. Присоедините deeplearning configuarion объект к нему. Установите 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')