主要内容

利用深度学习进行时间序列预测

这个例子展示了如何使用长短期记忆(LSTM)网络预测时间序列数据。

LSTM网络是一种循环神经网络(RNN),它通过随着时间步骤的循环和更新网络状态来处理输入数据。网络状态包含以前所有时间步骤中记住的信息。您可以使用LSTM网络预测一个时间序列或序列的后续值,使用之前的时间步长作为输入。为了训练用于时间序列预测的LSTM网络,训练具有序列输出的回归LSTM网络,其中响应(目标)是具有一个时间步移值的训练序列。也就是说,在输入序列的每一个时间步,LSTM网络都会学习预测下一个时间步的值。

预测方法有两种:开环预测和闭环预测。

  • 开环预测仅使用输入数据预测序列中的下一个时间步。在对后续时间步骤进行预测时,从数据源收集真实值并将其用作输入。例如,假设您想预测时间步长的值 t 使用在时间步骤1中收集的数据的序列 t - 1 。对时间步长进行预测 t + 1 ,等待,直到记录时间步长的真值 t 并将其作为下一个预测的输入。当你在进行下一次预测之前有真实的值可以提供给网络时,使用开环预测。

  • 闭环预测以之前的预测为输入,预测序列中后续的时间步长。在这种情况下,模型不需要真值来进行预测。例如,假设您想预测时间步长的值 t 通过 t + k 使用在时间步骤1中收集的数据的序列 t - 1 只有。对时间步长进行预测 时,时间步长用预测值 - 1 作为输入。使用闭环预测来预测多个后续时间步骤,或者在进行下一次预测之前没有真实值提供给网络时。

该图显示了使用闭环预测的预测值的示例序列。

本例使用波形数据集,其中包含2000个合成生成的具有三个通道的不同长度的波形。该示例训练LSTM网络,使用闭环和开环预测来预测先前时间步长的波形的未来值。

加载数据

从加载示例数据WaveformData.mat。数据是numObservations-by-1单元格序列数组,其中numObservations是序列的个数。每个序列都是numChannels——-numTimeSteps数字数组,其中numChannels信道数的序列和numTimeSteps是序列的时间步长。

负载WaveformData

查看前几个序列的大小。

数据(1:5)
ans =5×1单元格数组{3×103 double} {3×136 double} {3×140 double} {3×124 double} {3×127 double}

查看通道数。为了训练网络,每个序列必须有相同数量的通道。

numChannels = size(数据{1},1)
numChannels = 3

想象一个图中的前几个序列。

图tiledlayout (2, 2)nexttile stackkedplot (data{I}') xlabel(“时间步”结束

将数据划分为训练集和测试集。将90%的观察结果用于训练,其余的用于测试。

numObservations = numel(data);idxTrain = 1:地板(0.9*numObservations);idxTest = floor(0.9*numObservations)+1:numObservations;data(idxTrain);dataTest =数据(idxTest);

为培训准备数据

为了预测序列未来时间步长的值,将目标指定为值平移一个时间步的训练序列。也就是说,在输入序列的每一个时间步,LSTM网络都会学习预测下一个时间步的值。预测器是没有最后时间步长的训练序列。

n = 1: number (dataTrain) X = dataTrain{n};XTrain{n} = X(:,1:end-1);TTrain{n} = X(:,2:结束);结束

为了更好的拟合和防止训练发散,将预测器和目标归一化,使其具有零平均值和单位方差。在进行预测时,还必须使用与训练数据相同的统计数据对测试数据进行规范化。为了便于计算所有序列的平均值和标准偏差,在时间维度上连接序列。

muX = mean(cat(2,XTrain{:}),2);sigmaX = std(cat(2,XTrain{:}),0,2);muT = mean(cat(2,TTrain{:}),2);sigmaT = std(cat(2,TTrain{:}),0,2);n = 1: number (XTrain) XTrain{n} = (XTrain{n} - muX) ./ sigmaX;TTrain{n} = (TTrain{n} - muT) ./ sigmaT;结束

定义LSTM网络体系结构

创建一个LSTM回归网络。

  • 使用序列输入层,其输入大小与输入数据的通道数量相匹配。

  • 使用带有128个隐藏单位的LSTM层。隐藏单元的数量决定了该层学习到多少信息。使用更多的隐藏单元可以产生更准确的结果,但更有可能导致对训练数据的过度拟合。

  • 为了输出与输入数据的通道数量相同的序列,包括一个完全连接的层,其输出大小与输入数据的通道数量匹配。

  • 最后,包括一个回归层。

layers = [sequenceInputLayer(numChannels) lstmLayer(128) fullyConnectedLayer(numChannels) regressionLayer];

指定培训项目

指定培训选项。

  • 使用Adam优化训练。

  • 训练200个纪元。对于更大的数据集,您可能不需要为一个良好的拟合训练那么多的epoch。

  • 在每个小批中,左填充序列,使它们具有相同的长度。左填充防止网络预测序列末端的填充值。

  • 对每个纪元的数据进行洗牌。

  • 以图表形式展示训练进度。

  • 禁用详细输出。

选项= trainingOptions(“亚当”MaxEpochs = 200,SequencePaddingDirection =“左”洗牌=“every-epoch”情节=“训练进步”Verbose = 0);

训练神经网络

使用指定的训练选项训练LSTM网络trainNetwork函数。

net = trainNetwork(XTrain,TTrain,图层,选项);

测试网络

使用与训练数据相同的步骤准备用于预测的测试数据。

使用从训练数据中计算出的统计数据对测试数据进行归一化。将目标指定为值移了一个时间步的测试序列,将预测器指定为不移最后一个时间步的测试序列。

n = 1:size(dataTest,1) X =数据测试{n};XTest{n} = (X(:,1:end-1) - muX) ./ sigmaX;TTest{n} = (X(:,2:end) - muT) ./ sigmaT;结束

利用测试数据进行预测。指定与训练相同的填充选项。

YTest = predict(net,XTest,SequencePaddingDirection=“左”);

为了评估准确性,对于每个测试序列,计算预测和目标之间的均方根误差(RMSE)。

i = 1:尺寸(欧美,1)rmse (i) =√意味着(欧美{我}- tt{我})^ 2,。“所有”));结束

在直方图中可视化错误。数值越低,准确度越高。

图直方图(rmse)“RMSE”) ylabel (“频率”

计算所有测试观测值的平均RMSE。

(rmse)
ans =0.5080

预测未来时间步骤

给定一个输入时间序列或序列,要预测多个未来时间步长的值,可以使用predictAndUpdateState函数一次预测一个时间步长,并在每次预测时更新网络状态。对于每个预测,使用之前的预测作为函数的输入。

在图中可视化一个测试序列。

Idx = 2;X = XTest{idx};T = TTest{idx};图stackedplot (X ', DisplayLabels =“通道”+ (1:numChannels)) xlabel(“时间步”)标题(“试验观察”+ idx)

开环预测

开环预测仅使用输入数据预测序列中的下一个时间步。在对后续时间步骤进行预测时,从数据源中收集真实值并将其用作输入。例如,假设您想预测时间步长的值 t 使用在时间步骤1中收集的数据的序列 t - 1 。对时间步长进行预测 t + 1 ,等待,直到记录时间步长的真值 t 并将其作为下一个预测的输入。当你在进行下一次预测之前有真实的值可以提供给网络时,使用开环预测。

方法初始化网络状态,首先重置状态resetState函数,然后使用输入数据的前几个时间步进行初始预测。使用输入数据的前75个时间步来更新网络状态。

net = resetState(net);Offset = 75;[net,~] = predictAndUpdateState(net,X(:,1:offset));

方法进行时间步骤循环并更新网络状态,以预测进一步的预测predictAndUpdateState函数。通过对输入数据的时间步长进行循环,并将其作为网络的输入,来预测测试观测的剩余时间步长的值。第一个预测是与时间步长对应的值偏移量+ 1

numTimeSteps = size(X,2);numPredictionTimeSteps = numTimeSteps - offset;Y = 0 (numChannels,numPredictionTimeSteps);t = 1:numPredictionTimeSteps Xt = X(:,offset+t);[net,Y(:,t)] = predictAndUpdateState(net,Xt);结束

将预测值与目标值进行比较。

figure t = tiledlayout(numChannels,1);标题(t)“开环预测”i = 1:numChannels nexttile plot(T(i,:)) hold住情节(抵消:numTimeSteps [T(我,抵消)Y(我:)],“——”) ylabel (“通道”+ i)结束包含(“时间步”nexttile(1) legend([“输入”“预测”])

闭环预测

闭环预测以之前的预测为输入,预测序列中后续的时间步长。在这种情况下,模型不需要真值来进行预测。例如,假设您想预测时间步长的值 t 通过 t + k 使用在时间步骤1中收集的数据的序列 t - 1 只有。对时间步长进行预测 时,时间步长用预测值 - 1 作为输入。使用闭环预测来预测多个后续时间步骤,或者在进行下一次预测之前没有真实值可以提供给网络时。

方法初始化网络状态,首先重置状态resetState函数,然后进行初步预测Z使用输入数据的前几个时间步长。使用输入数据的前75个时间步来更新网络状态。

net = resetState(net);offset = size(X,2);[net,Z] = predictAndUpdateState(net,X);

方法进行时间步骤循环并更新网络状态,以预测进一步的预测predictAndUpdateState函数。通过将之前的预测值迭代传递给网络,预测接下来的200个时间步。由于网络不需要输入数据来进行任何进一步的预测,因此可以指定任意数量的时间步长进行预测。

numPredictionTimeSteps = 200;Xt = Z(:,end);Y = 0 (numChannels,numPredictionTimeSteps);t = 1:numPredictionTimeSteps [net,Y(:,t)] = predictAndUpdateState(net,Xt);Xt = Y(:,t);结束

在一个图表中可视化预测的值。

numTimeSteps = offset + numPredictionTimeSteps;figure t = tiledlayout(numChannels,1);标题(t)“闭环预测”i = 1:numChannels nexttile plot(T(i,1:offset)) hold住情节(抵消:numTimeSteps [T(我,抵消)Y(我:)],“——”) ylabel (“通道”+ i)结束包含(“时间步”nexttile(1) legend([“输入”“预测”])

闭环预测允许您预测任意数量的时间步长,但与开环预测相比可能不太准确,因为在预测过程中网络无法访问真实值。

另请参阅

|||

相关的话题