Генерация кода для сети LSTM на Raspberry Pi

В этом примере показано, как сгенерировать код для предварительно обученной сети долгой краткосрочной памяти (LSTM), которая пользуется Библиотекой ARM® Compute, и разверните код по цели Raspberry Pi™. В этом примере сеть LSTM предсказывает Остающийся срок полезного использования (RUL) машины. Сеть берет в качестве входных наборов данных временных рядов, которые представляют различные датчики в механизме. Сеть возвращает Остающийся Срок полезного использования механизма, измеренного в циклах, как его выход.

Этот пример использует Турбовентиляторный Набор Данных моделирования Ухудшения Engine как описано в [1]. Этот набор данных содержит 100 учебных наблюдений и 100 тестовых наблюдений. Обучающие данные содержат симулированные данные временных рядов для 100 механизмов. Каждая последовательность имеет 17 функций, варьируется по длине и соответствует полному экземпляру запуска к отказу (RTF). Тестовые данные содержат 100 частичных последовательностей и соответствующие значения Остающегося Срока полезного использования в конце каждой последовательности.

Этот пример использует предварительно обученную сеть LSTM. Для получения дополнительной информации о том, как обучить сеть LSTM, смотрите, что Классификация Последовательностей в качестве примера Использует Глубокое обучение.

Этот пример демонстрирует два разных подхода для выполнения предсказания при помощи сети LSTM:

  • Первый подход использует стандартную сеть LSTM и запускает вывод на наборе данных временных рядов.

  • Второй подход усиливает поведение с сохранением информации той же сети LSTM. В этом методе вы передаете один такт данных за один раз и имеете обновление сети ее состояние на каждом временном шаге.

Этот пример использует базирующийся рабочий процесс PIL, чтобы сгенерировать MEX-функцию, которая в свою очередь вызывает исполняемый файл, сгенерированный в целевом компьютере из MATLAB.

Строки кода в этом примере комментируются. Не прокомментируйте их, прежде чем вы запустите пример.

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

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

  • MATLAB® Coder™

  • Embedded Coder®

  • Deep Learning Toolbox™

  • Интерфейс MATLAB Coder для Библиотек Глубокого обучения. Чтобы установить этот пакет поддержки, используйте Add-On Explorer.

  • Пакет Поддержки MATLAB для Оборудования Raspberry Pi. Чтобы установить этот пакет поддержки, используйте Add-On Explorer.

  • Оборудование Raspberry Pi

  • ARM Вычисляет Библиотеку (на целевом оборудовании ARM)

  • Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, см. Стороннее Аппаратное и программное обеспечение (MATLAB Coder). Для подготовки переменных окружения смотрите Переменные окружения (MATLAB Coder).

Настройте объект настройки генерации кода для статической библиотеки

Чтобы сгенерировать MEX-функцию PIL для заданной функции точки входа, создайте объект настройки кода для статической библиотеки и установите режим верификации на 'PIL'. Установите выходной язык на C++.

% cfg = coder.config('lib', 'ecoder', true);
% cfg.VerificationMode = 'PIL';
% cfg.TargetLang = 'C++';

Настройте объект настройки для генерации кода глубокого обучения

Создайте coder.ARMNEONConfig объект. Задайте Вычислить версию Библиотеки. В данном примере предположите, что ARM Вычисляет Библиотеку в оборудовании Raspberry Pi, версия 19.05.

% dlcfg = coder.DeepLearningConfig('arm-compute');
% dlcfg.ArmComputeVersion = '19.05';

Установите DeepLearningConfig свойство настройки генерации кода возражает против объекта настройки глубокого обучения.

% cfg.DeepLearningConfig = dlcfg;

Создайте связь с Raspberry Pi

Использование Пакет Поддержки MATLAB для Raspberry Pi Поддерживает функцию Пакета, 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;

Первый подход: сгенерируйте MEX-функцию PIL для сети LSTM

В этом подходе вы генерируете код для функции точки входа rul_lstmnet_predict.

rul_lstmnet_predict.m функция точки входа берет целый набор данных временных рядов в качестве входа и передает его сети для предсказания. А именно, функция использует сеть LSTM, которая обучена в Классификации Последовательностей в качестве примера Используя Глубокое обучение. Функция загружает сетевой объект от rul_lstmnet.mat файл в персистентную переменную и повторные использования этот постоянный объект в последующих вызовах предсказания. Сеть LSTM от последовательности к последовательности позволяет вам сделать различные предсказания для каждого отдельного временного шага последовательности данных.

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

type('rul_lstmnet_predict.m')
function out =  rul_lstmnet_predict(in) %#codegen

% Copyright 2019 The MathWorks, Inc. 

persistent mynet;

if isempty(mynet)
    mynet = coder.loadDeepLearningNetwork('rul_lstmnet.mat');
end


out = mynet.predict(in); 

Сгенерировать код при помощи codegen (MATLAB Coder) команда, используйте coder.typeof (MATLAB Coder) функция, чтобы задать тип и размер входного параметра к функции точки входа. В этом примере вход имеет двойной тип данных со значением размерности признаков 17 и переменная длина последовательности. Задайте длину последовательности как переменный размер, чтобы выполнить предсказание на входной последовательности любой длины.

% matrixInput = coder.typeof(double(0),[17 Inf],[false true]);

Запуститесь codegen команда, чтобы сгенерировать PIL основывала MEX-функцию rul_lstmnet_predict_pil на серверной платформе.

% codegen -config cfg rul_lstmnet_predict -args {matrixInput} -report

Запустите сгенерированную MEX-функцию PIL на тестовых данных

Загрузите MAT-файл RULTestData. Этот MAT-файл хранит переменные XTest и YTest это содержит демонстрационный timeseries показаний датчика, на которых можно протестировать сгенерированный код. Это тестовые данные взято из Классификации Последовательностей в качестве примера Используя Глубокое обучение после предварительной обработки данных.

load RULTestData;

XTest переменная содержит 100 входных наблюдений. Каждое наблюдение имеет 17 функций с различной длиной последовательности.

XTest(1:5)
ans=5×1 cell array
    {17×31  double}
    {17×49  double}
    {17×126 double}
    {17×106 double}
    {17×98  double}

YTest переменная содержит 100 выходных наблюдений, которые соответствуют XTest входная переменная. Каждое выходное наблюдение является Остающимся Сроком полезного использования (RUI) значение, измеренное в циклах, для каждых данных о временном шаге в целой последовательности.

YTest(1:5)
ans=5×1 cell array
    {1×31  double}
    {1×49  double}
    {1×126 double}
    {1×106 double}
    {1×98  double}

Запустите сгенерированную MEX-функцию rul_lstmnet_predict_pil на установлены случайные тестовые данные.

% idx = randperm(numel(XTest), 1);
% inputData = XTest{idx};

% YPred1 = rul_lstmnet_predict_pil(inputData);

Сравните предсказания с тестовыми данными

Используйте график сравнить выходные данные MEX с тестовыми данными.

% figure('Name', 'Standard LSTM', 'NumberTitle', 'off');
%     
% plot(YTest{idx},'--')
% hold on
% plot(YPred1,'.-')
% hold off
% 
% ylim([0 175])
% title("Test Observation " + idx)
% xlabel("Time Step")
% ylabel("RUL measured in cycles")

Очистите PIL

% clear rul_lstmnet_predict_pil;

Второй подход: сгенерируйте MEX-функцию PIL для сети LSTM с сохранением информации

Вместо того, чтобы передать целые данные о timeseries целиком predict, можно запустить предсказание путем потоковой передачи входных данных, мудрых сегментом при помощи predictAndUpdateState функция.

Функция точки входа rul_lstmnet_predict_and_update.m принимает вход одно такта и обрабатывает его при помощи predictAndUpdateState функция. predictAndUpdateState возвращает предсказание в течение входного такта и обновляет сеть так, чтобы последующие части входа были обработаны как последующие такты той же выборки.

type('rul_lstmnet_predict_and_update.m')
function out = rul_lstmnet_predict_and_update(in) %#codegen

% Copyright 2019 The MathWorks, Inc. 

persistent mynet;

if isempty(mynet)
    mynet = coder.loadDeepLearningNetwork('rul_lstmnet.mat');
end

[mynet, out] = predictAndUpdateState(mynet, in);

end

Создайте входной тип для codegen команда. Поскольку rul_lstmnet_predict_and_update принимает одни данные такта в каждом вызове, укажите, что вход вводит matrixInput иметь фиксированную длину последовательности 1 вместо переменной длины последовательности.

% matrixInput = coder.typeof(double(0),[17 1]);

Запустите codegen команда, чтобы сгенерировать PIL основывала MEX-функцию rul_lstmnet_predict_and_update_pil на серверной платформе.

% codegen -config cfg rul_lstmnet_predict_and_update -args {matrixInput} -report

Запустите сгенерированную MEX-функцию PIL на тестовых данных

% Run generated MEX function(|rul_lstmnet_predict_and_update_pil|) for each
% time step data in the inputData sequence.

% sequenceLength = size(inputData,2);
% YPred2 = zeros(1, sequenceLength);
% for i=1:sequenceLength
%     inTimeStep = inputData(:,i);
%     YPred2(:, i) = rul_lstmnet_predict_and_update_pil(inTimeStep);
% end

После того, как вы передаете все такты, по одному, к rul_lstmnet_predict_and_update функция, получившийся выход совпадает с этим в первом подходе, в котором вы передали все входные параметры целиком.

Сравните предсказания с тестовыми данными

Используйте график сравнить выходные данные MEX с тестовыми данными.

% figure('Name', 'Statefull LSTM', 'NumberTitle', 'off');
% 
% 
% plot(YTest{idx},'--')
% hold on
% plot(YPred2,'.-')
% hold off
% 
% ylim([0 175])
% title("Test Observation " + idx)
% xlabel("Time Step")
% ylabel("RUL measured in cycles")

Очистите PIL

% clear rul_lstmnet_predict_and_update_pil;

Ссылки

[1] Saxena, Abhinav, Кай Гоебель, Дон Саймон и Нил Экланд. "Повредите моделирование распространения для симуляции запуска к отказу авиационного двигателя". В Предзнаменованиях и медицинском управлении, 2008. PHM 2008. Международная конференция по вопросам, стр 1-9. IEEE, 2008.

Смотрите также

| (MATLAB Coder) | (MATLAB Coder) | (MATLAB Coder)

Похожие темы