В этом примере показано, как создать код для приложения классификации изображений, использующего глубокое обучение. Он использует codegen команда для создания функции MEX, выполняющей прогнозирование с использованием сетей классификации изображений, таких как MobileNet-v2, ResNet и GoogLeNet.
Необходимый
В этом примере создается CUDA MEX со следующими требованиями сторонних производителей.
Графический процессор NVIDIA ® с поддержкой CUDA ® и совместимый драйвер.
Дополнительный
Для построений, отличных от MEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
Инструментарий NVIDIA.
Библиотека NVIDIA cuDNN.
Переменные среды для компиляторов и библиотек. Дополнительные сведения см. в разделах Аппаратное обеспечение сторонних производителей (GPU Coder) и Настройка необходимых продуктов (GPU Coder).
Используйте coder.checkGpuInstall Функция (GPU Coder) для проверки правильности настройки компиляторов и библиотек, необходимых для выполнения этого примера.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
mobilenetv2_predict Функция точки входаMobileNet-v2 - это сверточная нейронная сеть, которая обучена более чем миллиону изображений из базы данных ImageNet. Сеть имеет глубину 155 слоев и может классифицировать изображения на 1000 категорий объектов, таких как клавиатура, мышь, карандаш и многие животные. Сеть имеет размер входного изображения 224 на 224. Используйте analyzeNetwork функция для отображения интерактивной визуализации архитектуры сети глубокого обучения.
net = mobilenetv2(); analyzeNetwork(net);
mobilenetv2_predict.m функция точки входа принимает входной сигнал изображения и выполняет предсказание на изображении с использованием предварительно обученной MobileNet-v2 сверточной нейронной сети. Функция использует постоянный объект mynet для загрузки последовательного сетевого объекта и повторно использует постоянный объект для прогнозирования последующих вызовов.
type('mobilenetv2_predict.m')
% Copyright 2017-2019 The MathWorks, Inc.
function out = mobilenetv2_predict(in)
%#codegen
persistent mynet;
if isempty(mynet)
mynet = coder.loadDeepLearningNetwork('mobilenetv2','mobilenetv2');
end
% pass in input
out = mynet.predict(in);
Создание кода CUDA для mobilenetv2_predict создание объекта конфигурации кода GPU для цели MEX и установка целевого языка на C++. Используйте coder.DeepLearningConfig (Кодер графического процессора) для создания CuDNN глубокий объект конфигурации обучения и назначить его DeepLearningConfig свойства объекта конфигурации кода графического процессора. Запустить codegen и укажите размер ввода [224 224 3]. Это значение соответствует размеру входного уровня сети MobileNet-v2.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -config cfg mobilenetv2_predict -args {ones(224,224,3)} -report
Code generation successful: To view the report, open('codegen/mex/mobilenetv2_predict/html/report.mldatx').
Последовательная сеть создается как класс C++, содержащий массив из 155 классов уровней и функций для настройки, прогнозирования вызовов и очистки сети.
class b_mobilenetv2_0 { .... public: b_mobilenetv2_0(); void setup(); void predict(); void cleanup(); ~b_mobilenetv2_0(); };
setup() метод класса устанавливает дескрипторы и выделяет память для каждого уровня сетевого объекта. predict() способ выполняет прогнозирование для каждого из 155 уровней в сети.
Функция точки входа mobilenetv2_predict() в созданном кодовом файле mobilenetv2_predict.cu создает статический объект b_mobilenetv2 типа класса и вызывает установку и прогнозирование для этого сетевого объекта.
static b_mobilenetv2_0 mynet; static boolean_T mynet_not_empty;
/* Function Definitions */ void mobilenetv2_predict(const real_T in[150528], real32_T out[1000]) { if (!mynet_not_empty) { DeepLearningNetwork_setup(&mynet); mynet_not_empty = true; }
/* pass in input */ DeepLearningNetwork_predict(&mynet, in, out); }
Двоичные файлы экспортируются для слоев с такими параметрами, как полностью соединенные и сверточные слои в сети. Например, файлы cnn_mobilenetv2_conv*_w и cnn_mobilenetv2_conv*_b соответствуют весам и параметрам смещения для слоев свертки в сети. Чтобы просмотреть список созданных файлов, используйте:
dir(fullfile(pwd, 'codegen', 'mex', 'mobilenetv2_predict'))
Загрузите входное изображение.
im = imread('peppers.png');
imshow(im);

Звонить mobilenetv2_predict_mex на входном изображении.
im = imresize(im, [224,224]); predict_scores = mobilenetv2_predict_mex(double(im));
Получите пять лучших оценок прогнозирования и их метки.
[scores,indx] = sort(predict_scores, 'descend'); classNames = net.Layers(end).ClassNames; classNamesTop = classNames(indx(1:5)); h = figure; h.Position(3) = 2*h.Position(3); ax1 = subplot(1,2,1); ax2 = subplot(1,2,2); image(ax1,im); barh(ax2,scores(5:-1:1)) xlabel(ax2,'Probability') yticklabels(ax2,classNamesTop(5:-1:1)) ax2.YAxisLocation = 'right'; sgtitle('Top Five Predictions That Use MobileNet-v2')

Включенная вспомогательная функция mobilenet_live.m захватывает кадры из веб-камеры, выполняет прогнозирование и отображает результаты классификации на каждом из захваченных видеокадров. В этом примере используется webcam(Пакет поддержки MATLAB для веб-камер USB), который поддерживается пакетом поддержки MATLAB ® для Webcams™ USB. Пакет поддержки можно загрузить и установить с помощью программы установки пакета поддержки.
type('mobilenet_live.m')
% Copyright 2017-2019 The MathWorks, Inc.
function mobilenet_live
% Connect to a camera
camera = webcam;
% The labels with top 5 prediction scores are
% mapped to corresponding labels
net = mobilenetv2();
classnames = net.Layers(end).ClassNames;
imfull = zeros(224,400,3, 'uint8');
fps = 0;
ax = axes;
while true
% Take a picture
ipicture = camera.snapshot;
% Resize and cast the picture to single
picture = imresize(ipicture,[224,224]);
% Call MEX function for MobileNet-v2 prediction
tic;
pout = mobilenetv2_predict(single(picture));
newt = toc;
% fps
fps = .9*fps + .1*(1/newt);
% top 5 scores
[top5labels, scores] = getTopFive(pout,classnames);
% display
if isvalid(ax)
dispResults(ax, imfull, picture, top5labels, scores, fps);
else
break;
end
end
end
function dispResults(ax, imfull, picture, top5labels, scores, fps)
for k = 1:3
imfull(:,177:end,k) = picture(:,:,k);
end
h = imshow(imfull, 'InitialMagnification',200, 'Parent', ax);
scol = 1;
srow = 20;
text(get(h, 'Parent'), scol, srow, sprintf('MobileNet-v2 Demo'), 'color', 'w', 'FontSize', 20);
srow = srow + 20;
text(get(h, 'Parent'), scol, srow, sprintf('Fps = %2.2f', fps), 'color', 'w', 'FontSize', 15);
srow = srow + 20;
for k = 1:5
t = text(get(h, 'Parent'), scol, srow, top5labels{k}, 'color', 'w','FontSize', 15);
pos = get(t, 'Extent');
text(get(h, 'Parent'), pos(1)+pos(3)+5, srow, sprintf('%2.2f%%', scores(k)), 'color', 'w', 'FontSize', 15);
srow = srow + 20;
end
drawnow;
end
function [labels, scores] = getTopFive(predictOut,classnames)
[val,indx] = sort(predictOut, 'descend');
scores = val(1:5)*100;
labels = classnames(indx(1:5));
end
Очистить статический сетевой объект, загруженный в память.
clear mex;
Для классификации изображений можно также использовать сетевой ResNet-50 DAG. Предварительно подготовленная модель ResNet-50 для MATLAB доступна в пакете поддержки ResNet-50 Deep Learning Toolbox. Чтобы загрузить и установить пакет поддержки, используйте обозреватель надстроек. Дополнительные сведения о поиске и установке надстроек см. в разделе Получение надстроек и управление ими.
net = resnet50; disp(net)
DAGNetwork with properties:
Layers: [177×1 nnet.cnn.layer.Layer]
Connections: [192×2 table]
InputNames: {'input_1'}
OutputNames: {'ClassificationLayer_fc1000'}
Создание кода CUDA для resnet_predict.m создание объекта конфигурации кода GPU для цели MEX и установка целевого языка на C++. Эта функция точки входа вызывает resnet50 функция для загрузки сети и выполнения прогнозирования на входном изображении.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -config cfg resnet_predict -args {ones(224,224,3)} -report
Code generation successful: To view the report, open('codegen/mex/resnet_predict/html/report.mldatx').
Звонить resnet_predict_mex на входном изображении.
predict_scores = resnet_predict_mex(double(im));
Получите пять лучших оценок прогнозирования и их метки.
[scores,indx] = sort(predict_scores, 'descend'); classNames = net.Layers(end).ClassNames; classNamesTop = classNames(indx(1:5)); h = figure; h.Position(3) = 2*h.Position(3); ax1 = subplot(1,2,1); ax2 = subplot(1,2,2); image(ax1,im); barh(ax2,scores(5:-1:1)) xlabel(ax2,'Probability') yticklabels(ax2,classNamesTop(5:-1:1)) ax2.YAxisLocation = 'right'; sgtitle('Top Five Predictions That Use ResNet-50')

Очистить статический сетевой объект, загруженный в память.
clear mex;
Предварительно подготовленная модель GoogLeNet для MATLAB доступна в пакете поддержки GoogLeNet инструментария Deep Learning Toolbox. Чтобы загрузить и установить пакет поддержки, используйте обозреватель надстроек. Дополнительные сведения о поиске и установке надстроек см. в разделе Получение надстроек и управление ими.
net = googlenet; disp(net)
DAGNetwork with properties:
Layers: [144×1 nnet.cnn.layer.Layer]
Connections: [170×2 table]
InputNames: {'data'}
OutputNames: {'output'}
Создание кода CUDA для googlenet_predict.m функция точки входа. Эта функция точки входа вызывает googlenet функция для загрузки сети и выполнения прогнозирования на входном изображении. Чтобы создать код для этой функции точки входа, создайте объект конфигурации графического процессора для цели MEX.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -config cfg googlenet_predict -args {ones(224,224,3)} -report
Code generation successful: To view the report, open('codegen/mex/googlenet_predict/html/report.mldatx').
Звонить googlenet_predict_mex на входном изображении.
im = imresize(im, [224,224]); predict_scores = googlenet_predict_mex(double(im));
Получите пять лучших оценок прогнозирования и их метки.
[scores,indx] = sort(predict_scores, 'descend'); classNames = net.Layers(end).ClassNames; classNamesTop = classNames(indx(1:5)); h = figure; h.Position(3) = 2*h.Position(3); ax1 = subplot(1,2,1); ax2 = subplot(1,2,2); image(ax1,im); barh(ax2,scores(5:-1:1)) xlabel(ax2,'Probability') yticklabels(ax2,classNamesTop(5:-1:1)) ax2.YAxisLocation = 'right'; sgtitle('Top Five Predictions That Use GoogLeNet')

Очистить статический сетевой объект, загруженный в память.
clear mex;