Этот пример показывает, как предсказать оставшийся срок полезного использования (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")
Саксена, Абхинав, Кай Гебель, Дон Симон и Нил Эклунд. Моделирование распространения повреждений для симуляции пробега двигателя самолета до отказа. В прогнозах и управлении здоровьем, 2008. PHM 2008. Международная конференция, стр. 1-9. IEEE, 2008.
Саксена, Абхинав, Кай Гебель. «Набор данных моделирования деградации Engine». NASA Ames Prognostics Data Repository https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/, Исследовательский центр НАСА им. Эймса, Моффетт-Филд, Калифорния
lstmLayer
| predictAndUpdateState
| sequenceInputLayer
| trainingOptions
| trainNetwork