В этом примере показано, как создавать и развертывать код C++, использующий для прогнозирования объектов MobileNet-v2 предварительно подготовленную сеть.
Процессор ARM, поддерживающий расширение NEON
Вычислительная библиотека ARM (на целевом оборудовании ARM)
Библиотека компьютерного зрения с открытым исходным кодом (OpenCV) версии 2.4 (на целевом оборудовании ARM)
Переменные среды для компиляторов и библиотек
MATLAB ® Coder™
Пакет поддержки интерфейса кодера MATLAB для библиотек глубокого обучения
Глубокое обучение Toolbox™
Модель набора инструментов для глубокого обучения для пакета поддержки MobileNet-v2 Network
Toolbox™ обработки изображений
Пакет поддержки MATLAB для оборудования Raspberry Pi
Версия библиотеки вычислений ARM, используемая в этом примере, может не быть последней версией, поддерживаемой при создании кода. Поддерживаемые версии библиотек и сведения о настройке переменных среды см. в разделе Предварительные условия для глубокого обучения с помощью кодера MATLAB.
Этот пример не поддерживается для MATLAB online.
В этом примере сетевой MobileNet-v2 группы обеспечения доступности баз данных используется для классификации изображений с помощью вычислительной библиотеки ARM ®. Предварительно подготовленная сеть MobileNet-v2 для MATLAB доступна в пакете поддержки Deep Learning Toolbox Model for MobileNet-v2 Network.
При создании кода, использующего вычислительную библиотеку ARM и пакет аппаратной поддержки, codegen генерирует код на хост-компьютере, копирует сгенерированные файлы на целевое оборудование и создает исполняемый файл на целевом оборудовании.
mobilenet_predict Функция mobilenet_predict функция вызывает метод прогнозирования MobileNet-v2 сетевого объекта на входном изображении и возвращает результат оценки прогнозирования. Вызов функции coder.updateBuildInfo для указания параметров связывания для созданного make-файла.
type mobilenet_predict
function out = mobilenet_predict(in)
persistent net;
opencv_linkflags = '`pkg-config --cflags --libs opencv`';
coder.updateBuildInfo('addLinkFlags',opencv_linkflags);
if isempty(net)
net = coder.loadDeepLearningNetwork('mobilenetv2', 'mobilenet');
end
out = net.predict(in);
end
Создайте объект конфигурации генерации кода C++.
cfg = coder.config('exe'); cfg.TargetLang = 'C++';
Укажите использование библиотеки вычислений ARM. Вычислительная библиотека ARM обеспечивает оптимизированную функциональность для оборудования Raspberry Pi. Чтобы создать код, использующий библиотеку вычислений ARM, создайте coder.ARMNEONConfig объект. Укажите версию вычислительной библиотеки ARM, установленной на Raspberry Pi, и архитектуру Raspberry Pi. Присоедините объект конфигурации глубокого обучения к объекту конфигурации генерации кода.
dlcfg = coder.DeepLearningConfig('arm-compute'); supportedVersions = dlcfg.getARMComputeSupportedVersions; dlcfg.ArmArchitecture = 'armv7'; dlcfg.ArmComputeVersion = '19.05'; cfg.DeepLearningConfig = dlcfg;
Используйте функцию «Пакет поддержки MATLAB для аппаратных средств Raspberry Pi» raspi для создания соединения с Raspberry Pi. В этом коде замените:
raspiname с ведущим именем вашего Малинового Пи
username с именем пользователя
password с вашим паролем
r = raspi('raspiname','username','password');
Создать coder.Hardware объект для Raspberry Pi и присоедините его к объекту конфигурации генерации кода.
hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;
Укажите папку сборки на Raspberry Pi:
buildDir = '~/remoteBuildDir';
cfg.Hardware.BuildDir = buildDir;
Укажите основной файл main_mobilenet.cpp в объекте конфигурации генерации кода. Файл вызывает сгенерированный код C++ для mobilenet_predict функция. Файл считывает входное изображение, передает данные сгенерированным вызовам функции, извлекает предсказания на изображении и печатает оценки предсказания в файл.
cfg.CustomSource = 'main_mobilenet.cpp';
Создать код C++. При использовании codegen с пакетом поддержки MATLAB для оборудования Raspberry PI исполняемый файл построен на Raspberry Pi.
Для создания кода необходимо задать переменные среды. ARM_COMPUTELIB и LD_LIBRARY_PATH на Малиновом Пи.
codegen -config cfg mobilenet_predict -args {ones(224, 224, 3,'single')} -report
Для проверки созданного кода на Raspberry Pi скопируйте введенное изображение в созданную папку кода. Эту папку можно найти вручную или с помощью raspi.utils.getRemoteBuildDirectory API. Эта функция перечисляет папки двоичных файлов, созданных с помощью codegen. Если двоичный файл найден только в одной папке, введите:
applicationDirPaths = raspi.utils.getRemoteBuildDirectory('applicationName','mobilenet_predict'); targetDirPath = applicationDirPaths{1}.directory;
Для копирования файлов, необходимых для запуска исполняемой программы, используйте putFile.
r.putFile('peppers_raspi_mobilenet.png',targetDirPath);
Запустите исполняемую программу на Raspberry Pi из MATLAB и направьте выходные данные обратно в MATLAB.
exeName = 'mobilenet_predict.elf'; argsforexe = ' peppers_raspi_mobilenet.png '; % Provide the input image; command = ['cd ' targetDirPath ';sudo ./' exeName argsforexe]; output = system(r,command);
outputfile = [targetDirPath, '/output.txt'];
r.getFile(outputfile);
Сопоставьте пять лучших оценок прогнозирования с соответствующими метками в обученной сети и просмотрите выходные данные.
type mapPredictedScores_mobilenet
%% Map the Prediction Scores to Labels and Display Output
net = mobilenetv2;
ClassNames = net.Layers(end).ClassNames;
%% Read the classification
fid = fopen('output.txt') ;
S = textscan(fid,'%s');
fclose(fid) ;
S = S{1} ;
predict_scores = cellfun(@(x)str2double(x), S);
%% Remove NaN values that were strings
predict_scores(isnan(predict_scores))=[];
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
top5labels = ClassNames(indx(1:5));
%% Display classification labels on the image
im = imread('peppers_raspi_mobilenet.png');
im = imresize(im, [224 224]);
outputImage = zeros(224,400,3, 'uint8');
for k = 1:3
outputImage(:,177:end,k) = im(:,:,k);
end
scol = 1;
srow = 1;
outputImage = insertText(outputImage, [scol, srow], 'Classification with MobileNetv2', '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);

coder.ARMNEONConfig | coder.DeepLearningConfig | coder.hardware