В этом примере показано, как сгенерировать типовой исполняемый файл C/C++, который не зависит ни от каких сторонних библиотек глубокого обучения от глубокого обучения модель Simulink®. Пример предсказывает остающийся срок полезного использования (RUL) турбовентиляторного механизма, измеренного в циклах на каждом шаге входных временных рядов, которые представляют данные из различных датчиков в механизме.
Для видеодемонстрации этого примера смотрите, Генерируют Типовой Код C/C++ для Нейронных сетей для глубокого обучения в Simulink.
Этот пример на основе Того, чтобы генерировать Типовой Код C/C++ для Регрессии От последовательности к последовательности Который пример Глубокого обучения Использования от MATLAB® Coder™. Для получения дополнительной информации смотрите, Генерируют Типовой Код C/C++ для Регрессии От последовательности к последовательности Который Глубокое обучение Использования.
Для верификации PIL вам будет нужно:
STM32F407G-открытие STMicroelectronics, STM32F746G-открытие или плата STM32F769I-открытия
Тип A USB к кабелю Mini-B
Кабель USB TTL-232 - TTL-232R 3.3 В (последовательная передача для платы STM32F4-открытия)
Embedded Coder® Support Package для Советов Открытия STMicroelectronics. Чтобы установить этот пакет поддержки, используйте меню Add-Ons в разделе Environment вкладки MATLAB Home.
Этот пример использует предварительно обученную сеть LSTM, чтобы предсказать остающийся срок полезного использования механизма, измеренного в циклах. Сеть LSTM состоит из слоя LSTM с 200 скрытыми модулями, сопровождаемыми полносвязным слоем размера 50 и слоя уволенного с вероятностью уволенного 0.5. Сеть была обучена с помощью Турбовентиляторного Набора Данных моделирования Ухудшения Engine как описано в [1]. Обучающие данные содержат симулированные данные временных рядов для 100 механизмов. Каждая последовательность варьируется по длине и соответствует полному экземпляру запуска к отказу (RTF). Тестовые данные содержат 100 частичных последовательностей и соответствующие значения остающегося срока полезного использования в конце каждой последовательности. Для получения дополнительной информации об обучении сети смотрите, что Регрессия От последовательности к последовательности в качестве примера Использует Глубокое обучение (Deep Learning Toolbox).
net = coder.loadDeepLearningNetwork('rulNetwork.mat')
net = SeriesNetwork with properties: Layers: [6×1 nnet.cnn.layer.Layer] InputNames: {'sequenceinput'} OutputNames: {'regressionoutput'}
Для получения информации о сетях слои и классы, поддержанные для генерации кода, видят Сети и Слои, Поддержанные для Генерации кода.
Загрузите TurboFanRULValidate
MAT-файл, который содержит Турбовентиляторный Набор данных Валидации Ухудшения Engine. Этот MAT-файл хранит переменную XValidate
это содержит 100 демонстрационных наблюдений, представляющих показания датчика, которые вы используете, чтобы протестировать модель Simulink.
load('TurboFanRULValidate.mat')
Чтобы сделать данные о контроле ввода совместимыми с генерацией кода Simulink, длины последовательности для каждого из независимых 100 наблюдений дополнены нулем, чтобы создать однородно измеренный, 17 303 входные массивы.
sequenceLengths = cellfun(@length,XValidate,'UniformOutput',true); maxSequenceLen = max(sequenceLengths); padFcn = @(x) [x,zeros(size(x,1),maxSequenceLen-size(x,2))]; XValidatePad = cellfun(padFcn,XValidate,'UniformOutput',false);
Заполненные значения затем преобразованы в 17 303 100 числовыми массивами. Чтобы импортировать эти данные в модель Simulink, задайте переменную структуры, содержащую значения данных и пустой временной вектор. В процессе моделирования вход впервые шаг читается сначала 17 303 элемент массива. Значение для шага второго раза читается из второго элемента, и так далее, для в общей сложности 100 шагов.
simin.time = []; simin.signals.values = cell2mat(reshape(XValidatePad,1,1,[])); simin.signals.dimensions = size(XValidatePad{1});
Модель Simulink для предсказывает, что остающийся срок полезного использования турбовентиляторного механизма показывают. Модель использует Predict
блок из Deep Neural Networks
библиотека, которая импортирует обучивший сеть из rulNetwork
Matfile. Кроме того, Mini-batch size
параметр блока устанавливается на 1.
model = 'rulPredict';
open_system(model)
Чтобы подтвердить модель Simulink, запустите симуляцию.
set_param(model,'SimulationMode','Normal'); sim(model);
Выход YPred
из Simulink модель содержит предсказанные остающиеся значения срока полезного использования от сети. Этот выход сначала обрезан, чтобы удалить результаты дополненных нулем значений и затем преобразован в массив ячеек.
YPred_cell = squeeze(mat2cell(YPred,1,maxSequenceLen,ones(1,100))); for t = 1:length(sequenceLengths) YPred_cell{t}(:,sequenceLengths(t) + 1:end) = []; end
Постройте предсказанные значения остающегося срока полезного использования (RUL) для четырех случайным образом выбранных наблюдений и сравните их с данными о валидации.
observationIdx = randperm(100,4); rulExamplePlots(observationIdx,YValidate,YPred_cell);
Чтобы сгенерировать код C/C++, который не зависит ни от каких сторонних библиотек глубокого обучения и создает исполняемый файл, выберите дженерик, в реальном времени (ERT) цель от Embedded Coder™.
cs = getActiveConfigSet(model);
switchTarget(cs,'ert.tlc',[]);
Сконфигурируйте генерацию кода определенные параметры. Установка логгирования MAT-файла позволяет сгенерированному коду перенаправить данные моделирования к MAT-файлу.
set_param(cs,'TargetLang','C'); set_param(cs,'Toolchain','Automatically locate an installed toolchain'); set_param(cs,'ObjectivePriorities','Execution efficiency'); set_param(cs,'DLTargetLibrary','None'); set_param(cs,'GenerateReport','on'); set_param(cs,'CodeInterfacePackaging','Nonreusable function'); set_param(cs,'MatFileLogging', 'on');
Сгенерируйте и создайте модель Simulink при помощи slbuild
команда. Генератор кода помещает файлы в папку сборки, подпапка, названная rulPredict_ert_rtw
под вашей текущей рабочей папкой.
evalc("slbuild('rulPredict')");
Запустите сгенерированный исполняемый файл. После успешного выполнения, rulPredict
исполняемый файл создает rulPredict
MAT-файл в текущей рабочей папке.
if ispc status = system('rulPredict.exe'); else status = system('./rulPredict'); end
** created rulPredict.mat **
load('rulPredict.mat')
Выход rt_YPred
содержит предсказанные остающиеся значения срока полезного использования от сети. Этот выход сначала обрезан, чтобы удалить результаты дополненных нулем значений и затем преобразован в массив ячеек.
rt_YPred_cell = squeeze(mat2cell(rt_YPred,1,maxSequenceLen,ones(1,100))); for t = 1:length(sequenceLengths) rt_YPred_cell{t}(:,sequenceLengths(t) + 1:end) = []; end
Постройте предсказанные значения остающегося срока полезного использования (RUL) для четырех случайным образом выбранных наблюдений и сравните их с данными о валидации.
rulExamplePlots(observationIdx,YValidate,rt_YPred_cell);
Чтобы гарантировать, что поведение кода развертывания совпадает с проектом, можно сконфигурировать модель Simulink, чтобы запустить PIL симуляцию на встроенных платах. В PIL симуляции сгенерированный код работает на встроенных платах, таких как STMicroelectronics® Discovery. Результаты PIL симуляции передаются Simulink, чтобы проверить числовую эквивалентность симуляции и результатов генерации кода.
Этот пример показывает верификацию PIL на плате Открытия STMicroelectronics при помощи Embedded Coder® Support Package для Советов Открытия STMicroelectronics. Этот пример предварительно сконфигурирован, чтобы работать на плате STM32F746G-открытия. Можно сконфигурировать эту модель, чтобы использовать другие поддерживаемые встроенные платы путем выбора их как "Аппаратной платы" на панели Аппаратной реализации Параметров конфигурации Модели.
Для PIL симуляции этот пример сортирует наблюдения по длине последовательности и выбирает первые 10. Эти наблюдения дополнены нулем, чтобы создать однородно измеренный, 17 54 входные массивы. Заполненные значения затем преобразованы в 17 54 10 числовых массивов. Чтобы импортировать эти данные в модель Simulink, задайте переменную структуры, содержащую значения данных и пустой временной вектор. В процессе моделирования вход впервые шаг читается сначала 17 54 элемент массива. Значение для шага второго раза читается из второго элемента, и так далее, для в общей сложности 10 шагов.
[~,idx] = sort(cellfun(@length,XValidate)); XValidatePIL = XValidate(idx(1:10)); YValidatePIL = YValidate(idx(1:10)); sequenceLengths = cellfun(@length,XValidatePIL,'UniformOutput',true); maxSequenceLen = max(sequenceLengths); padFcn = @(x) [x,zeros(size(x,1),maxSequenceLen-size(x,2))]; XValidatePILPad = cellfun(padFcn,XValidatePIL,'UniformOutput',false); simin.time = []; simin.signals.values = cell2mat(reshape(XValidatePILPad,1,1,[])); simin.signals.dimensions = size(XValidatePILPad{1});
rulPredict_pil
модифицированная версия rulPredict
модель для верификации PIL. Загружать тестовые векторы, rulPredict_pil
модель заменяет From Workspace
блокируйтесь с Inport
блок. Inport
блок сконфигурирован, чтобы принять 17 54 массив двойного типа данных.
pilModel = 'rulPredict_pil';
open_system(pilModel);
Сконфигурируйте rulPredict_pil
модель для цели STM32F467G-открытия.
cs = getActiveConfigSet(pilModel); set_param(cs,'HardwareBoard','STM32F746G-Discovery'); set_param(cs,'Toolchain','GNU Tools for ARM Embedded Processors');
Плата STM32F4-открытия поддерживает два различных коммуникационных интерфейса для PIL: ST-LINK и последовательный. Коммуникационный интерфейс ST-LINK не требует никаких дополнительных кабелей, или оборудование помимо типа A USB к кабелю Mini-B раньше соединяло плату STM32F4-открытия с хостом - компьютером. Последовательный интерфейс требует кабеля USB TTL-232. Выполнение PIL симуляции с помощью последовательного интерфейса намного быстрее, чем выполнение PIL симуляции с помощью ST-LINK. Этот пример сконфигурирован, чтобы использовать последовательный интерфейс.
Кроме того, необходимо установить параметр COM-порта в Параметрах конфигурации> Аппаратная реализация> Ресурсы Целевого компьютера> PIL, чтобы совпадать с номером порта последовательного интерфейса на компьютере Windows.
Чтобы сравнить результаты PIL с симуляцией, запустите rulPredict_pil
модель в режиме normal mode и затем в режиме PIL.
set_param(cs,'LoadExternalInput','on'); set_param(cs, 'ExternalInput','simin'); set_param(pilModel,'SimulationMode','Normal'); sim(pilModel); YPred_ref = YPred_pil; set_param(pilModel,'SimulationMode','Processor-in-the-Loop (PIL)') sim(pilModel);
Выход YPred_pil
и YPred_ref
содержите предсказанные остающиеся значения срока полезного использования от сети. Этот выход сначала обрезан, чтобы удалить результаты дополненных нулем значений и затем преобразован в массив ячеек.
Постройте предсказанные значения остающегося срока полезного использования (RUL) для PIL и сравните их с данными о валидации.
YPred_ref_cell = squeeze(mat2cell(YPred_ref,1,maxSequenceLen,ones(1,10))); YPred_pil_cell = squeeze(mat2cell(YPred_pil,1,maxSequenceLen,ones(1,10))); for t = 1:length(sequenceLengths) YPred_ref_cell{t}(:,sequenceLengths(t) + 1:end) = []; YPred_pil_cell{t}(:,sequenceLengths(t) + 1:end) = []; end rulExamplePlots([1:10],YValidatePIL,YPred_pil_cell);
Вычислите ошибку из PIL симуляции и постройте результаты.
YPred_error = YPred_ref-YPred_pil; figure('Name', 'PIL Error') for i = 1:10 subplot(5,2,i) plot(YPred_error(:,:,i),'.-') maxerror = string(max(YPred_error(:,:,i))); ylim([-1e-4 1e-4]) title("Test Observation " + i) xlabel("Time Step") ylabel("Difference") end legend(["Difference in Simulation Modes"],'Location','southeast')
function rulExamplePlots(observationIdx,YTest,YPred) N = numel(observationIdx); figure for i = 1:N subplot(N/2,2,i) plot(YTest{observationIdx(i)},'--') hold on plot(YPred{observationIdx(i)},'.-') hold off ylim([0 175]) title("Test Observation " + observationIdx(i)) xlabel("Time Step") ylabel("RUL") end legend(["Test Data" "Predicted"],'Location','southeast') end
Saxena, Abhinav, Кай Гоебель, Дон Саймон и Нил Экланд. "Повредите моделирование распространения для симуляции запуска к отказу авиационного двигателя". В Предзнаменованиях и медицинском управлении, 2008. PHM 2008. Международная конференция по вопросам, стр 1-9. IEEE, 2008.