Сгенерируйте Типовой Код C/C++ для Регрессии От последовательности к последовательности, Которая Использует Глубокое обучение

Этот пример демонстрирует, как сгенерировать плоскость код C/C++, который не зависит ни от каких сторонних библиотек глубокого обучения для сети долгой краткосрочной памяти (LSTM). Вы генерируете MEX-функцию, которая принимает данные временных рядов, представляющие различные датчики в механизме. MEX-функция затем делает предсказания для каждого шага входного timeseries, чтобы предсказать остающийся срок полезного использования (RUL) механизма, измеренного в циклах.

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

Задайте функцию точки входа rulPredict

rulPredict функция точки входа берет входную последовательность и передает ее обученной сети LSTM от последовательности к последовательности для предсказания. Функция загружает сетевой объект от rulNetwork.mat файл в персистентную переменную и повторные использования постоянный объект на последующих вызовах предсказания. Сеть LSTM делает предсказания на частичной последовательности одним временным шагом за один раз. На каждом временном шаге сеть предсказывает использование значения на этом временном шаге и сетевого состояния, вычисленного от предыдущих временных шагов только. Сеть обновляет свое состояние между каждым предсказанием. predict функция возвращает последовательность этих предсказаний. Последний элемент предсказания соответствует предсказанному RUL для частичной последовательности.

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

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

% Copyright 2020 The MathWorks, Inc. 

persistent mynet;

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

% pass in input to predict method
% To prevent the function from adding padding to the data, specify the mini-batch size 1. 
out = predict(mynet,in,'MiniBatchSize',1);

Запустите rulPredict на тестовых данных

Загрузите TurboFanRULValidate Matfile. Этот MAT-файл хранит переменную XValidate это содержит демонстрационные данные о timeseries для показаний датчика, которые вы используют, чтобы протестировать функцию точки входа в MATLAB. Сделайте предсказания на тестовых данных путем вызова rulPredict метод.

load TurboFanRULValidate.mat
YPred = rulPredict(XValidate);

Визуализируйте некоторые предсказания в графике.

idx = randperm(numel(YPred),4);
figure
for i = 1:numel(idx)
    subplot(2,2,i)
    
    plot(YValidate{idx(i)},'--')
    hold on
    plot(YPred{idx(i)},'.-')
    hold off
    
    ylim([0 175])
    title("Test Observation " + idx(i))
    xlabel("Time Step")
    ylabel("RUL")
end
legend(["Test Data" "Predicted"],'Location','southeast')

Figure contains 4 axes. Axes 1 with title Test Observation 82 contains 2 objects of type line. Axes 2 with title Test Observation 90 contains 2 objects of type line. Axes 3 with title Test Observation 13 contains 2 objects of type line. Axes 4 with title Test Observation 89 contains 2 objects of type line. These objects represent Test Data, Predicted.

Для данной частичной последовательности предсказанный текущий RUL является последним элементом предсказанных последовательностей. Вычислите среднеквадратичную ошибку (RMSE) предсказаний и визуализируйте ошибку предсказания в гистограмме.

YValidateLast = zeros(1, numel(YValidate));
YPredLast = zeros(1, numel(YValidate));
for i = 1:numel(YValidate)
    YValidateLast(i) = YValidate{i}(end);
    YPredLast(i) = YPred{i}(end);
end
figure
rmse = sqrt(mean((YPredLast - YValidateLast).^2))
rmse = 19.0286
histogram(YPredLast - YValidateLast)
title("RMSE = " + rmse)
ylabel("Frequency")
xlabel("Error")

Figure contains an axes. The axes with title RMSE = 19.0286 contains an object of type histogram.

Сгенерируйте MEX-функцию для rulPredict

Сгенерировать MEX-функцию для rulPredict функция точки входа, создайте объект cfg настройки генерации кода для генерации кода MEX. Создайте объект настройки глубокого обучения, который указывает, что никакая целевая библиотека не требуется, и присоедините этот объект настройки глубокого обучения к cfg.

cfg = coder.config('mex');
cfg.DeepLearningConfig = coder.DeepLearningConfig('TargetLibrary','none');

По умолчанию выходной язык установлен в C. Если вы хотите сгенерировать Код С++, явным образом установите выходной язык на C++.

Используйте coder.typeof функция, чтобы создать входной тип для точки входа функционирует rulPredict то, что вы используете с -args опция в codegen команда.

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

matrixInput = coder.typeof(0, [17 Inf],[false true]); % input type for a single observation
cellInput = coder.typeof({matrixInput}, [100 1]); % input type for multiple observations 

Запустите codegen команду. Задайте входной тип, чтобы быть cellInput.

codegen -config cfg rulPredict -args {cellInput} -report
Code generation successful: To view the report, open('codegen/mex/rulPredict/html/report.mldatx').

По умолчанию для генерации кода MEX, сгенерированный код вызывает в библиотеку BLAS для операций над матрицей и пользуется библиотекой OpenMP (если компилятор поддерживает OpenMP) так, чтобы любые parallelizable циклы for в MEX могли работать на нескольких продвижении потоков к лучшей эффективности выполнения. В то время как OpenMP включен по умолчанию для автономной генерации кода, необходимо будет обеспечить пользовательский коллбэк BLAS, чтобы указать к MATLAB Coder ™, что вы хотите сгенерировать BLAS, призывает к операциям над матрицей, выполняющим шаги, упомянутые в, Ускоряют Матричные операции в Сгенерированном Автономном Коде при помощи Вызовов BLAS (MATLAB Coder).

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

Сделайте предсказания на тестовых данных путем вызова сгенерированной MEX-функции rulPredict_mex.

YPredMex = rulPredict_mex(XValidate);

Можно визуализировать те же предсказания как прежде в графике.

figure
for i = 1:numel(idx)
    subplot(2,2,i)
    
    plot(YValidate{idx(i)},'--')
    hold on
    plot(YPredMex{idx(i)},'.-')
    hold off
    
    ylim([0 175])
    title("Test Observation " + idx(i))
    xlabel("Time Step")
    ylabel("RUL")
end
legend(["Test Data" "Predicted MEX"],'Location','southeast')

Figure contains 4 axes. Axes 1 with title Test Observation 82 contains 2 objects of type line. Axes 2 with title Test Observation 90 contains 2 objects of type line. Axes 3 with title Test Observation 13 contains 2 objects of type line. Axes 4 with title Test Observation 89 contains 2 objects of type line. These objects represent Test Data, Predicted MEX.

Вычислите среднеквадратичную ошибку (RMSE) предсказаний и визуализируйте ошибку предсказания в гистограмме.

YPredLastMex = zeros(1, numel(YValidate));
for i = 1:numel(YValidate)
    YPredLastMex(i) = YPredMex{i}(end);
end
figure
rmse = sqrt(mean((YPredLastMex - YValidateLast).^2))
rmse = 19.0286
histogram(YPredLastMex - YValidateLast)
title("RMSE = " + rmse)
ylabel("Frequency")
xlabel("Error")

Figure contains an axes. The axes with title RMSE = 19.0286 contains an object of type histogram.

Сгенерируйте MEX-функцию с LSTM С сохранением информации

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

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

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

% Copyright 2020 The MathWorks, Inc. 

persistent mynet;

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

% pass in input to predictAndUpdateState method
[mynet, out] = predictAndUpdateState(mynet, in);

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

matrixInput = coder.typeof(double(0),[17 1]);
codegen -config cfg rulPredictAndUpdate -args {matrixInput} -report
Code generation successful: To view the report, open('codegen/mex/rulPredictAndUpdate/html/report.mldatx').

Сделайте предсказания на тестовых данных путем вызова rulPredictAndUpdate функция в MATLAB and the сгенерированная MEX-функция rulPredictAndUpdate_mex.

YPredStatefulMex = cell(numel(idx), 1);
for iSample = 1:numel(idx)
    sample = XValidate{idx(iSample)};
    numTimeStepsTest = size(sample, 2);
    for iStep = 1:numTimeStepsTest
        YPredStatefulMex{iSample}(1, iStep) = rulPredictAndUpdate_mex(sample(:, iStep));
    end
end

Еще раз можно визуализировать предсказания для MEX с сохранением информации как прежде в графике.

figure
for i = 1:numel(idx)
    subplot(2,2,i)
    
    plot(YValidate{idx(i)},'--')
    hold on
    plot(YPredStatefulMex{i},'.-')
    hold off
    
    ylim([0 175])
    title("Test Observation " + idx(i))
    xlabel("Time Step")
    ylabel("RUL")
end
legend(["Test Data" "Predicted MEX Stateful LSTM"],'Location','southeast')

Figure contains 4 axes. Axes 1 with title Test Observation 82 contains 2 objects of type line. Axes 2 with title Test Observation 90 contains 2 objects of type line. Axes 3 with title Test Observation 13 contains 2 objects of type line. Axes 4 with title Test Observation 89 contains 2 objects of type line. These objects represent Test Data, Predicted MEX Stateful LSTM.

Наконец можно также визуализировать результаты для двух различных MEX-функций наряду с предсказанием MATLAB в графике для какой-то конкретной выборки.

figure()
sampleIdx = idx(1);
plot(YValidate{sampleIdx},'--')
hold on
plot(YPred{sampleIdx},'o-')
plot(YPredMex{sampleIdx},'^-')
plot(YPredStatefulMex{1},'x-')
hold off

ylim([0 175])
title("Test Observation " + idx(i))
xlabel("Time Step")
ylabel("RUL")
legend(["Test Data" "Predicted in MATLAB" "Predicted MEX" "Predicted MEX with Stateful LSTM"],'Location','southeast')

Figure contains an axes. The axes with title Test Observation 89 contains 4 objects of type line. These objects represent Test Data, Predicted in MATLAB, Predicted MEX, Predicted MEX with Stateful LSTM.

Ссылки

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

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

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

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте