Генерация кода для сети 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.

Примечания:

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

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

  • Этот пример не поддерживается в 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).

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

Чтобы сгенерировать 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
    {[                                                                                                                                                                                                                                                                                                                                                             142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112]}
    {[                                                                                                                                                                                                                                                                                       146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98]}
    {[150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 149 148 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69]}
    {[                                                                   150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 149 148 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82]}
    {[                                                                                          150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150 149 148 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91]}

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

Похожие темы