В этом примере показано, как прогнозировать данные временных рядов с использованием сети LSTM.
Для прогнозирования значений будущих временных шагов последовательности можно обучить сеть регрессии последовательности к последовательности LSTM, где ответами являются обучающие последовательности со значениями, сдвинутыми на один временной шаг. То есть на каждом временном шаге входной последовательности сеть LSTM учится предсказывать значение следующего временного шага.
Для прогнозирования значений нескольких временных шагов в будущем используйте predictAndUpdateState функция для предсказания временных шагов по одному и обновления состояния сети при каждом предсказании.
В этом примере используется набор данных chickenpox_dataset. Пример обучает сеть LSTM прогнозировать количество случаев ветряной оспы с учетом количества случаев в предыдущие месяцы.
Загрузите данные примера. chickenpox_dataset содержит один временной ряд с временными шагами, соответствующими месяцам, и значениями, соответствующими количеству случаев. Выходные данные представляют собой массив ячеек, где каждый элемент представляет собой один временной шаг. Измените форму данных на вектор строки.
data = chickenpox_dataset;
data = [data{:}];
figure
plot(data)
xlabel("Month")
ylabel("Cases")
title("Monthly Cases of Chickenpox")
Разбиение данных обучения и тестирования. Обучение на первых 90% последовательности и тестирование на последних 10%.
numTimeStepsTrain = floor(0.9*numel(data)); dataTrain = data(1:numTimeStepsTrain+1); dataTest = data(numTimeStepsTrain+1:end);
Для лучшего соответствия и предотвращения расхождения данных обучения стандартизируйте данные обучения, чтобы они имели нулевое среднее значение и отклонение единиц измерения. Во время прогнозирования необходимо стандартизировать данные теста с использованием тех же параметров, что и данные обучения.
mu = mean(dataTrain); sig = std(dataTrain); dataTrainStandardized = (dataTrain - mu) / sig;
Чтобы спрогнозировать значения будущих временных шагов последовательности, укажите ответы, которые должны быть обучающими последовательностями со значениями, сдвинутыми на один временной шаг. То есть на каждом временном шаге входной последовательности сеть LSTM учится предсказывать значение следующего временного шага. Предикторами являются обучающие последовательности без последнего временного шага.
XTrain = dataTrainStandardized(1:end-1); YTrain = dataTrainStandardized(2:end);
Создание регрессионной сети LSTM. Укажите уровень LSTM, содержащий 200 скрытых единиц.
numFeatures = 1;
numResponses = 1;
numHiddenUnits = 200;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits)
fullyConnectedLayer(numResponses)
regressionLayer];Укажите параметры обучения. Задайте для решателя значение 'adam' и тренируются на 250 эпох. Для предотвращения разузлования градиентов установите порог градиента равным 1. Укажите начальную скорость обучения 0,005 и уменьшите скорость обучения после 125 эпох путем умножения на коэффициент 0,2.
options = trainingOptions('adam', ... 'MaxEpochs',250, ... 'GradientThreshold',1, ... 'InitialLearnRate',0.005, ... 'LearnRateSchedule','piecewise', ... 'LearnRateDropPeriod',125, ... 'LearnRateDropFactor',0.2, ... 'Verbose',0, ... 'Plots','training-progress');
Обучение сети LSTM с использованием указанных вариантов обучения trainNetwork.
net = trainNetwork(XTrain,YTrain,layers,options);

Для прогнозирования значений нескольких временных шагов в будущем используйте predictAndUpdateState функция для предсказания временных шагов по одному и обновления состояния сети при каждом предсказании. Для каждого предсказания используйте предыдущее предсказание в качестве входных данных функции.
Стандартизация данных тестирования с использованием тех же параметров, что и данные обучения.
dataTestStandardized = (dataTest - mu) / sig; XTest = dataTestStandardized(1:end-1);
Чтобы инициализировать состояние сети, сначала спрогнозируйте данные обучения. XTrain. Затем выполните первое прогнозирование с использованием последнего временного шага обучающего ответа. YTrain(end). Закольцевать оставшиеся прогнозы и ввести предыдущее предсказание в predictAndUpdateState.
Для больших коллекций данных, длинных последовательностей или больших сетей прогнозы на GPU обычно вычисляются быстрее, чем прогнозы на CPU. В противном случае предсказания на CPU обычно вычисляются быстрее. Для прогнозирования одного шага времени используйте CPU. Чтобы использовать CPU для прогнозирования, установите 'ExecutionEnvironment' вариант predictAndUpdateState кому 'cpu'.
net = predictAndUpdateState(net,XTrain); [net,YPred] = predictAndUpdateState(net,YTrain(end)); numTimeStepsTest = numel(XTest); for i = 2:numTimeStepsTest [net,YPred(:,i)] = predictAndUpdateState(net,YPred(:,i-1),'ExecutionEnvironment','cpu'); end
Отмените стандартизацию прогнозов с использованием параметров, рассчитанных ранее.
YPred = sig*YPred + mu;
График хода обучения показывает среднеквадратическую ошибку (RMSE), вычисленную на основе стандартизированных данных. Вычислите RMSE из нестандартных прогнозов.
YTest = dataTest(2:end); rmse = sqrt(mean((YPred-YTest).^2))
rmse = single
248.5531
Постройте график временных рядов обучения с прогнозными значениями.
figure plot(dataTrain(1:end-1)) hold on idx = numTimeStepsTrain:(numTimeStepsTrain+numTimeStepsTest); plot(idx,[data(numTimeStepsTrain) YPred],'.-') hold off xlabel("Month") ylabel("Cases") title("Forecast") legend(["Observed" "Forecast"])

Сравните прогнозируемые значения с данными теста.
figure subplot(2,1,1) plot(YTest) hold on plot(YPred,'.-') hold off legend(["Observed" "Forecast"]) ylabel("Cases") title("Forecast") subplot(2,1,2) stem(YPred - YTest) xlabel("Month") ylabel("Error") title("RMSE = " + rmse)

При наличии доступа к фактическим значениям временных шагов между прогнозами можно обновить состояние сети наблюдаемыми значениями вместо прогнозируемых значений.
Сначала инициализируйте состояние сети. Чтобы предсказать новую последовательность, сбросьте состояние сети с помощью resetState. Сброс состояния сети предотвращает влияние предыдущих прогнозов на прогнозы новых данных. Сбросьте состояние сети, а затем инициализируйте состояние сети путем прогнозирования данных обучения.
net = resetState(net); net = predictAndUpdateState(net,XTrain);
Спрогнозировать на каждом временном шаге. Для каждого предсказания спрогнозируйте следующий временной шаг, используя наблюдаемое значение предыдущего временного шага. Установите 'ExecutionEnvironment' вариант predictAndUpdateState кому 'cpu'.
YPred = []; numTimeStepsTest = numel(XTest); for i = 1:numTimeStepsTest [net,YPred(:,i)] = predictAndUpdateState(net,XTest(:,i),'ExecutionEnvironment','cpu'); end
Отмените стандартизацию прогнозов с использованием параметров, рассчитанных ранее.
YPred = sig*YPred + mu;
Вычислите среднеквадратическую ошибку (RMSE).
rmse = sqrt(mean((YPred-YTest).^2))
rmse = 158.0959
Сравните прогнозируемые значения с данными теста.
figure subplot(2,1,1) plot(YTest) hold on plot(YPred,'.-') hold off legend(["Observed" "Predicted"]) ylabel("Cases") title("Forecast with Updates") subplot(2,1,2) stem(YPred - YTest) xlabel("Month") ylabel("Error") title("RMSE = " + rmse)

Здесь прогнозы более точны при обновлении состояния сети наблюдаемыми значениями вместо прогнозируемых значений.
lstmLayer | sequenceInputLayer | trainingOptions | trainNetwork