Генерация кода и развертывание MobileNet-v2 сети на Raspberry Pi

В этом примере показано, как сгенерировать и развернуть код С++, который использует MobileNet-v2 предварительно обученную сеть для предсказания объектов.

Необходимые условия

  • Процессор ARM, поддерживающий расширение NEON

  • ARM Compute Library (на целевом оборудовании ARM)

  • Open Source Computer Vision Library (OpenCV) версии 2.4 (на целевом оборудовании ARM)

  • Переменные окружения для компиляторов и библиотек

  • MATLAB ® Coder™

  • Пакет поддержки MATLAB Coder Interface for Глубокое Обучение Libraries

  • Deep Learning Toolbox™

  • Модель Deep Learning Toolbox для MobileNet-v2 пакета поддержки сети

  • Image Processing Toolbox™

  • Пакет поддержки MATLAB для оборудования Raspberry Pi

Версия библиотеки ARM Compute, которую использует этот пример, может быть не последней версией, которая поддержки генерацию кода. Для поддерживаемых версий библиотек и для получения информации о настройке переменных окружения, смотрите Необходимые условия для глубокого обучения с MATLAB Coder.

Этот пример не поддерживается для MATLAB в интерактивном режиме.

Этот пример использует сетевую MobileNet-v2 DAG для выполнения классификации изображений с помощью библиотеки ARM ® Compute Library. Предварительно обученная сеть MobileNet-v2 для MATLAB доступна в пакете Deep Learning Toolbox Model для MobileNet-v2 Network поддержки.

Когда вы генерируете код, который использует ARM Compute Library и пакет аппаратной поддержки, codegen генерирует код на хост-компьютер, копирует сгенерированные файлы в целевой компьютер и создает исполняемый файл на целевой компьютер.

Сконфигурируйте генерацию кода для mobilenet_predict Функция

The 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

Создайте объект Кода С++ генерации строения.

cfg = coder.config('exe');
cfg.TargetLang = 'C++';

Задайте использование вычислительной библиотеки ARM. ARM Compute Library обеспечивает оптимизированную функциональность для оборудования Raspberry Pi. Чтобы сгенерировать код, который использует ARM Compute Library, создайте coder.ARMNEONConfig объект. Укажите версию ARM Compute Library, установленную на вашем Raspberry Pi, и архитектуру Raspberry Pi. Присоедините объект строения глубокого обучения к объекту строения генерации кода.

dlcfg = coder.DeepLearningConfig('arm-compute');
supportedVersions = dlcfg.getARMComputeSupportedVersions;
dlcfg.ArmArchitecture = 'armv7';
dlcfg.ArmComputeVersion = '19.05';
cfg.DeepLearningConfig = dlcfg;

Создайте соединение с Raspberry Pi

Используйте функцию MATLAB Support Package for Raspberry Pi Hardware raspi для создания соединения с Raspberry Pi. В этом коде замените:

  • raspiname с именем хоста вашего Raspberry Pi

  • username с вашим именем пользователя

  • password с вашим паролем

r = raspi('raspiname','username','password');

Сконфигурируйте аппаратные параметры генерации кода для Raspberry Pi

Создайте coder.Hardware объект для Raspberry Pi и присоедините его к объекту строения генерации кода.

hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;

Укажите папку сборки на Raspberry Pi:

buildDir = '~/remoteBuildDir';
cfg.Hardware.BuildDir = buildDir;

Предоставьте основной файл C++

Укажите основной файл main_mobilenet.cpp в объекте строения генерации кода. Файл вызывает сгенерированный код С++ для mobilenet_predict функция. Файл считывает вход изображение, передает данные сгенерированным вызовам функций, извлекает предсказания на изображении и печатает предсказание счетов в файл.

cfg.CustomSource = 'main_mobilenet.cpp';

Сгенерируйте исполняемую программу на Raspberry Pi

Сгенерируйте код С++. Когда вы используете codegen с MATLAB Support Package for Raspberry PI Hardware, исполняемый файл построен на Raspberry Pi.

Для генерации кода необходимо задать Переменные окружения ARM_COMPUTELIB и LD_LIBRARY_PATH на Raspberry Pi.

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;

Скопируйте файлы примера в Raspberry Pi

Чтобы скопировать файлы, необходимые для запуска исполняемой программы, используйте putFile.

r.putFile('peppers_raspi_mobilenet.png',targetDirPath);

Запуск исполняемой программы на Raspberry Pi

Запустите исполняемую программу на 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);

Получите счета предсказания для 1000 выходных классов сети

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);

См. также

| |

Похожие темы