Регрессия последовательность-в-последовательности с использованием глубокого обучения

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

Чтобы обучить глубокую нейронную сеть предсказывать числовые значения из временных рядов или данных последовательности, можно использовать сеть долгой краткосрочной памяти (LSTM).

Этот пример использует набор данных моделирования деградации Engine Turbofan, как описано в [1]. Пример обучает сеть LSTM прогнозировать оставшийся срок службы двигателя (прогнозирующее обслуживание), измеренный в циклах, учитывая данные временных рядов, представляющие различные датчики в двигателе. Обучающие данные содержат моделируемые данные временных рядов для 100 двигателей. Каждая последовательность изменяется в длине и соответствует полному прогону в отказ (RTF) образца. Эти тестовые данные содержат 100 частичных последовательности и соответствующие значения оставшегося срока службы в конце каждой последовательности.

Набор данных содержит 100 обучающих наблюдений и 100 тестовых наблюдений.

Загрузка данных

Загрузите и разархивируйте набор данных моделирования деградации Engine Turbofan из https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/ [2].

Каждые временные ряды набора данных моделирования деградации Engine Turbofan представляют другой механизм. Каждый двигатель запускается с неизвестных степеней начального износа и изменения в производстве. Двигатель работает нормально в начале каждых временных рядов и развивает отказ в какой-то момент во время серии. В наборе обучающих данных отказ растет в величине до отказа системы.

Данные содержат сжатые ZIP текстовые файлы с 26 столбцами чисел, разделенными пространствами. Каждая строка является моментальным снимком данных, взятых в течение одного рабочего цикла, и каждый столбец является другой переменной. Столбцы соответствуют следующим:

  • Столбец 1 - Номер модуля

  • Столбец 2 - Время в циклах

  • Столбцы 3-5 - Операционные настройки

  • Столбцы 6-26 - Измерения датчика 1-21

Создайте директорию для хранения набора данных моделирования деградации Engine Turbofan.

dataFolder = fullfile(tempdir,"turbofan");
if ~exist(dataFolder,'dir')
    mkdir(dataFolder);
end

Загрузите и извлечите набор данных моделирования деградации Engine Turbofan из https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/.

Разархивируйте данные из файла CMAPSSData.zip.

filename = "CMAPSSData.zip";
unzip(filename,dataFolder)

Подготовка обучающих данных

Загрузите данные с помощью функции processTurboFanDataTrain прилагается к этому примеру. Функция processTurboFanDataTrain извлекает данные из filenamePredictors и возвращает массивы ячеек XTrain и YTrain, которые содержат обучающий предиктор и последовательности отклика.

filenamePredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,YTrain] = processTurboFanDataTrain(filenamePredictors);

Удаление функций с постоянными значениями

Функции, которые остаются постоянными для всех временных шагов, могут негативно повлиять на обучение. Найдите строки данных с одинаковыми минимальными и максимальными значениями и удалите строки.

m = min([XTrain{:}],[],2);
M = max([XTrain{:}],[],2);
idxConstant = M == m;

for i = 1:numel(XTrain)
    XTrain{i}(idxConstant,:) = [];
end

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

numFeatures = size(XTrain{1},1)
numFeatures = 17

Нормализуйте предикторы обучения

Нормализуйте предикторы обучения, чтобы иметь нулевое среднее и единичное отклонение. Чтобы вычислить среднее и стандартное отклонение по всем наблюдениям, сгруппируйте данные последовательности горизонтально.

mu = mean([XTrain{:}],2);
sig = std([XTrain{:}],0,2);

for i = 1:numel(XTrain)
    XTrain{i} = (XTrain{i} - mu) ./ sig;
end

Отклики клипов

Чтобы узнать больше из данных последовательности, когда двигатели близки к отказу, клипсируйте ответы на пороге 150. Это заставляет сеть рассматривать образцы с более высокими значениями RUL как равные.

thr = 150;
for i = 1:numel(YTrain)
    YTrain{i}(YTrain{i} > thr) = thr;
end

Этот рисунок показывает первое наблюдение и соответствующий обрезанный ответ.

Подготовка данных к заполнению

Чтобы минимизировать количество заполнения, добавляемое в мини-пакеты, отсортируйте обучающие данные по длине последовательности. Затем выберите мини-пакет размера, который разделяет обучающие данные равномерно и уменьшает количество заполнения в мини-пакетах.

Сортировка обучающих данных по длине последовательности.

for i=1:numel(XTrain)
    sequence = XTrain{i};
    sequenceLengths(i) = size(sequence,2);
end

[sequenceLengths,idx] = sort(sequenceLengths,'descend');
XTrain = XTrain(idx);
YTrain = YTrain(idx);

Просмотрите отсортированные длины последовательности на столбчатой диаграмме.

figure
bar(sequenceLengths)
xlabel("Sequence")
ylabel("Length")
title("Sorted Data")

Выберите мини-пакет, который разделяет обучающие данные равномерно и уменьшает количество заполнения в мини-пакетах. Задайте мини-пакет размером 20. Этот рисунок иллюстрирует заполнение, добавленное к несортированным и отсортированным последовательностям.

miniBatchSize = 20;

Определение сетевой архитектуры

Определите сетевую архитектуру. Создайте сеть LSTM, которая состоит из уровня LSTM с 200 скрытыми модулями, далее следует полностью соединенный слой размера 50 и слой отсева с вероятностью отсева 0,5.

numResponses = size(YTrain{1},1);
numHiddenUnits = 200;

layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits,'OutputMode','sequence')
    fullyConnectedLayer(50)
    dropoutLayer(0.5)
    fullyConnectedLayer(numResponses)
    regressionLayer];

Задайте опции обучения. Обучите на 60 эпох с мини-пакетами размера 20 с помощью решателя 'adam'. Задайте скорость обучения 0.01. Чтобы предотвратить разнесение градиентов, установите порог градиента равным 1. Чтобы сохранить сортировку последовательностей по длине, установите 'Shuffle' на 'never'.

maxEpochs = 60;
miniBatchSize = 20;

options = trainingOptions('adam', ...
    'MaxEpochs',maxEpochs, ...
    'MiniBatchSize',miniBatchSize, ...
    'InitialLearnRate',0.01, ...
    'GradientThreshold',1, ...
    'Shuffle','never', ...
    'Plots','training-progress',...
    'Verbose',0);

Обучите сеть

Обучите сеть с помощью trainNetwork.

net = trainNetwork(XTrain,YTrain,layers,options);

Тестируйте сеть

Подготовьте тестовые данные с помощью функции processTurboFanDataTest прилагается к этому примеру. Функция processTurboFanDataTest извлекает данные из filenamePredictors и filenameResponses и возвращает массивы ячеек XTest и YTest, которые содержат предиктор теста и последовательности отклика, соответственно.

filenamePredictors = fullfile(dataFolder,"test_FD001.txt");
filenameResponses = fullfile(dataFolder,"RUL_FD001.txt");
[XTest,YTest] = processTurboFanDataTest(filenamePredictors,filenameResponses);

Удалите функции с постоянными значениями с помощью idxConstant вычисляется из обучающих данных. Нормализуйте предикторы теста, используя те же параметры, что и в обучающих данных. Обрезка тестовых ответов на том же пороге, что и для обучающих данных.

for i = 1:numel(XTest)
    XTest{i}(idxConstant,:) = [];
    XTest{i} = (XTest{i} - mu) ./ sig;
    YTest{i}(YTest{i} > thr) = thr;
end

Делайте предсказания по тестовым данным, используя predict. Чтобы предотвратить добавление функции заполнения к данным, задайте размер мини-пакета 1.

YPred = predict(net,XTest,'MiniBatchSize',1);

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

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

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

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

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

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

Ссылки

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

  2. Саксена, Абхинав, Кай Гебель. «Набор данных моделирования деградации Engine». NASA Ames Prognostics Data Repository https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/, Исследовательский центр НАСА им. Эймса, Моффетт-Филд, Калифорния

См. также

| | | |

Похожие темы