В этом примере показано, как сгенерировать и развернуть код для прогноза на Raspberry Pi™ при помощи codegen
с пакетом поддержки MATLAB для оборудования Raspberry Pi.
Когда вы генерируете код для прогноза, пользующегося Библиотекой ARM® Compute и пакетом аппаратной поддержки, codegen
генерирует код по хосту - компьютеру, копирует сгенерированные файлы в целевой компьютер и создает исполняемый файл на целевом компьютере.
Процессор ARM, который поддерживает расширение NEON
ARM Вычисляет Библиотеку (на целевом оборудовании ARM)
Библиотека компьютерного зрения с открытым исходным кодом
Переменные окружения для компиляторов и библиотек
MATLAB® Coder™
Интерфейс MATLAB Coder пакета поддержки для Глубокого обучения
Deep Learning Toolbox™
Пакет поддержки Модель Deep Learning Toolbox для Сети SqueezeNet
Пакет поддержки MATLAB для оборудования Raspberry Pi
Для поддерживаемых версий библиотек и для получения информации о подготовке переменных окружения, смотрите Предпосылки для Глубокого обучения для MATLAB Coder. Этот пример не поддержан для MATLAB Online.
squeezenet_raspi_predict
ФункцияЭтот пример использует сеть DAG SqueezeNet, чтобы показать, что классификация изображений с ARM Вычисляет Библиотеку. Предварительно обученный SqueezeNet для MATLAB доступен в пакете поддержки Модель Deep Learning Toolbox для Сети SqueezeNet. squeezenet_arm_predict
функционируйте загружает сеть SqueezeNet в персистентный сетевой объект. На последующих вызовах функции снова используется постоянный объект.
Так, чтобы сгенерированная исполняемая программа соединилась против библиотек OpenCV, squeezenet_arm_predict
функция задает опции компоновщика при помощи coder.updateBuildInfo
.
type squeezenet_raspi_predict
% Copyright 2018 The MathWorks, Inc. function out = squeezenet_raspi_predict(in) %#codegen % A persistent object mynet is used to load the DAGNetwork object. % At the first call to this function, the persistent object is constructed and % set up. 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 net; opencv_linkflags = '`pkg-config --cflags --libs opencv`'; coder.updateBuildInfo('addLinkFlags',opencv_linkflags); if isempty(net) net = coder.loadDeepLearningNetwork('squeezenet', 'squeezenet'); end out = net.predict(in); end
Создайте объект настройки генерации кода для генерации исполняемой программы. Задайте генерацию Кода С++.
cfg = coder.config('exe'); cfg.TargetLang = 'C++';
Создайте coder.ARMNEONConfig
объект. Задайте версию библиотеки ARM Compute, которая находится на Raspberry Pi. Задайте архитектуру Raspberry Pi.
dlcfg = coder.DeepLearningConfig('arm-compute'); dlcfg.ArmArchitecture = 'armv7'; dlcfg.ArmComputeVersion = '19.02';
cfg.DeepLearningConfig = dlcfg;
Использование Пакет Поддержки MATLAB для Raspberry Pi Поддерживает функцию Пакета, raspi
, создать связь с Raspberry Pi. В следующем коде, замене:
raspiname
с именем вашего Raspberry Pi
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;
C++ основной файл читает входное изображение, прогноз запусков на изображении, и отображает метки классификации на изображении.
Задайте основной файл в объекте настройки генерации кода.
cfg.CustomSource = 'main_squeezenet_raspi.cpp';
Используйте codegen
сгенерировать Код С++. Когда вы используете codegen
с Пакетом Поддержки MATLAB для Оборудования Raspberry Pi исполняемый файл основан на Raspberry Pi.
Убедитесь, что вы устанавливаете переменные окружения ARM_COMPUTELIB и LD_LIBRARY_PATH на Raspberry Pi. Смотрите Предпосылки для Глубокого обучения для MATLAB Coder.
codegen -config cfg squeezenet_raspi_predict -args {ones(227, 227, 3,'single')} -report
Чтобы протестировать сгенерированный код на Raspberry Pi, скопируйте входное изображение в директорию сгенерированного кода. Можно найти эту директорию вручную или при помощи raspi.utils.getRemoteBuildDirectory
API. Эта функция перечисляет директории двоичных файлов, которые сгенерированы при помощи codegen
. Предположение, что двоичный файл найден только в одной директории, введите:
applicationDirPaths = raspi.utils.getRemoteBuildDirectory('applicationName','squeezenet_raspi_predict'); targetDirPath = applicationDirPaths{1}.directory;
Чтобы скопировать файлы, требуемые запускать исполняемую программу, используйте putFile
, который доступен с Пакетом Поддержки MATLAB для Оборудования Raspberry Pi.
r.putFile('synsetWords_squeezenet_raspi.txt', targetDirPath); r.putFile('coffeemug.png',targetDirPath);
Запустите исполняемую программу на Raspberry Pi из MATLAB и направьте выход назад к MATLAB.
exeName = 'squeezenet_raspi_predict.elf'; argsforexe = ' coffeemug.png '; % Provide the input image; command = ['cd ' targetDirPath ';./' exeName argsforexe]; output = system(r,command)
outputfile = [targetDirPath, '/output.txt'];
r.getFile(outputfile);
Сопоставьте лучшие пять баллов прогноза с соответствующими метками в обучившем сеть.
net = squeezenet; ClassNames = net.Layers(end).ClassNames;
Считайте классификацию.
fid = fopen('output.txt') ; S = textscan(fid,'%s'); fclose(fid) ; S = S{1} ; predict_scores = cellfun(@(x)str2double(x), S);
Удалите значения NaN, которые были строками.
predict_scores(isnan(predict_scores))=[];
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
top5labels = ClassNames(indx(1:5));
Отобразите метки классификации на изображении.
im = imread('coffeemug.png'); im = imresize(im, [227 227]); outputImage = zeros(227,400,3, 'uint8'); for k = 1:3 outputImage(:,174:end,k) = im(:,:,k); end scol = 1; srow = 1; outputImage = insertText(outputImage, [scol, srow], 'Classification with Squeezenet', '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