В этом примере показано, как предсказать остающийся срок полезного использования (RUL) механизмов при помощи глубокого обучения.
Чтобы обучить глубокую нейронную сеть предсказывать числовые значения от временных рядов или данных о последовательности, можно использовать сеть долгой краткосрочной памяти (LSTM).
Этот пример использует Турбовентиляторный Набор Данных моделирования Ухудшения Engine как описано в [1]. Пример обучает сеть LSTM, чтобы предсказать остающийся срок полезного использования механизма (прогнозирующее обслуживание), измеренный в циклах, учитывая данные временных рядов, представляющие различные датчики в механизме. Обучающие данные содержат симулированные данные временных рядов для 100 механизмов. Каждая последовательность имеет 17 функций, варьируется по длине и соответствует полному экземпляру запуска к отказу (RTF). Тестовые данные содержат 100 частичных последовательностей и соответствующие значения остающегося срока полезного использования в конце каждой последовательности.
Набор данных содержит 100 учебных наблюдений и 100 тестовых наблюдений.
Загрузите и разархивируйте Турбовентиляторный Набор Данных моделирования Ухудшения Engine от https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/[2].
Каждые временные ряды представляют различный механизм. Каждый механизм запускается с неизвестных степеней начального износа и производственного изменения. Механизм действует обычно в начале каждых временных рядов и разрабатывает отказ в какой-то момент во время ряда. В наборе обучающих данных отказ растет в величине до системного отказа.
Данные содержат сжатые до zip текстовые файлы с 26 столбцами чисел, разделенных пробелами. Каждая строка является снимком состояния данных, взятых во время одного рабочего цикла, и каждый столбец является различной переменной. Столбцы соответствуют следующему:
Столбец 1: Модульный номер
Столбец 2: Время в циклах
Столбцы 3-5: Операционные настройки
Столбцы 6-26: измерения Датчика 1–17
filename = "CMAPSSData.zip"; dataFolder = "data"; unzip(filename,dataFolder)
Загрузите данные с помощью функционального preprocessDataTrain
показанный в конце этого примера. Функциональный prepareDataTrain
извлекает данные из filenamePredictors
и возвращает массивы ячеек XTrain
и YTrain
, которые содержат учебный предиктор и последовательности ответа.
filenamePredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,YTrain] = prepareDataTrain(filenamePredictors);
Удалите функции с постоянными значениями
Функции, которые остаются постоянными навсегда, продвигаются, может негативно повлиять на обучение. Найдите строки данных, которые имеют те же минимальные и максимальные значения и удаляют строки.
m = min([XTrain{:}],[],2); M = max([XTrain{:}],[],2); idxConstant = M == m; for i = 1:numel(XTrain) XTrain{i}(idxConstant,:) = []; end
Нормируйте учебные предикторы
Нормируйте учебные предикторы, чтобы иметь нулевое среднее значение и модульное отклонение. Чтобы вычислить среднее и стандартное отклонение по всем наблюдениям, конкатенируйте данные о последовательности горизонтально.
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); featureDimension = size(XTrain{1},1); numHiddenUnits = 200; layers = [ ... sequenceInputLayer(featureDimension) 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);
Подготовьте тестовые данные с помощью функционального prepareDataTest
показанный в конце примера. Функциональный prepareDataTest
извлекает данные из filenamePredictors
и filenameResponses
и возвращает массивы ячеек XTest
и YTest
, которые содержат тестовый предиктор и последовательности ответа, соответственно.
filenamePredictors = fullfile(dataFolder,"test_FD001.txt"); filenameResponses = fullfile(dataFolder,"RUL_FD001.txt"); [XTest,YTest] = prepareDataTest(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 делает прогнозы на частичной последовательности одним временным шагом за один раз. На каждом временном шаге сеть предсказывает использование значения на этом временном шаге и сетевого состояния, вычисленного от предыдущих временных шагов только. Сеть обновляет свое состояние между каждым прогнозом. 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))
rmse = single
16.9854
histogram(YPredLast - YTestLast) title("RMSE = " + rmse) ylabel("Frequency") xlabel("Error")
Функциональный prepareDataTrain
извлекает данные из filenamePredictors
и возвращает массивы ячеек XTrain
и YTrain
которые содержат учебный предиктор и последовательности ответа, соответственно.
Данные содержат сжатые до zip текстовые файлы с 26 столбцами чисел, разделенных пробелами. Каждая строка является снимком состояния данных, взятых во время одного рабочего цикла, и каждый столбец является различной переменной. Столбцы соответствуют следующему:
1: Модульный номер
2: Время в циклах
3–5: Операционные настройки
6–26: Измерения датчика 1–17
function [XTrain,YTrain] = prepareDataTrain(filenamePredictors) dataTrain = dlmread(filenamePredictors); numObservations = max(dataTrain(:,1)); XTrain = cell(numObservations,1); YTrain = cell(numObservations,1); for i = 1:numObservations idx = dataTrain(:,1) == i; X = dataTrain(idx,3:end)'; XTrain{i} = X; timeSteps = dataTrain(idx,2)'; Y = fliplr(timeSteps); YTrain{i} = Y; end end
Функциональный prepareDataTest
извлекает данные из filenamePredictors
и filenameResponses
и возвращает массивы ячеек XTest
и YTest
, которые содержат тестовый предиктор и последовательности ответа. В filenamePredictors
, временные ряды заканчивают некоторое время до системного отказа. Данные в filenameResponses
обеспечивает вектор истинных значений RUL для тестовых данных.
function [XTest,YTest] = prepareDataTest(filenamePredictors,filenameResponses) XTest = prepareDataTrain(filenamePredictors); RULTest = dlmread(filenameResponses); numObservations = numel(RULTest); YTest = cell(numObservations,1); for i = 1:numObservations X = XTest{i}; sequenceLength = size(X,2); rul = RULTest(i); YTest{i} = rul+sequenceLength-1:-1:rul; end end
lstmLayer
| predictAndUpdateState
| sequenceInputLayer
| trainNetwork
| trainingOptions
[1] Saxena, Abhinav, Кай Гоебель, Дон Саймон и Нил Экланд. "Повредите моделирование распространения для симуляции запуска к отказу авиационного двигателя". В Предзнаменованиях и медицинском управлении, 2008. PHM 2008. Международная конференция по вопросам, стр 1-9. IEEE, 2008.
[2] Saxena, Abhinav, Кай Гоебель. "Турбовентиляторный Набор Данных моделирования Ухудшения Engine". НАСА Репозиторий данных Предзнаменований Эймса https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/, Исследовательский центр Эймса, Поле Moffett, CA