此示例显示了如何使用长短期内存(LSTM)网络预测时间序列数据。
为了预测序列的未来时间步长的值,您可以培训序列到序列回归LSTM网络,其中响应是具有一个时间步长的值的训练序列。即在输入序列的每个时间步长,LSTM网络学习预测下一个时间步长的值。
若要预测未来多个时间步长的值,请使用predictAndUpdateState
函数来预测时间步骤一次一个,并在每次预测时更新网络状态。
此示例使用数据集水痘_dataset
。该示例训练LSTM网络,根据前几个月的病例数预测水痘病例数。
加载示例数据。水痘_dataset
包含单个时间序列,时间步长对应于月,值对应于病例数。输出是一个单元数组,其中每个元素都是一个时间步长。将数据重塑为行向量。
数据= chickenpox_dataset;数据=({}):数据;图绘制(数据)包含(“月”)ylabel(“案例”) 标题(“水痘每月案例”)
对训练和测试数据进行分区。对序列的前90%进行训练,对最后10%进行测试。
numtimestepstrain =地板(0.9 * numel(数据));DataTrain =数据(1:NumtimeStepstrain + 1);DataTest =数据(NumtimeStepstrain + 1:结束);
为了更好地拟合和防止训练发散,对训练数据进行标准化,使其均值和单位方差为零。在预测时,必须使用与训练数据相同的参数标准化测试数据。
mu =卑鄙(数据标rain);sig = std(DataTrain);DataTrainstandardized =(DataTrain - mu)/ sig;
为了预测序列未来的时间步长值,将响应指定为移动一个时间步长的训练序列。即在输入序列的每个时间步长,LSTM网络学习预测下一个时间步长的值。预测因子是没有最后时间步长的训练序列。
XTrain = DataTrain标准(1:端1);Ytrain = DataTrain标准(2:结束);
创建LSTM回归网络。指定LSTM层以具有200个隐藏单元。
numFeatures = 1;numResponses = 1;numHiddenUnits = 200;层= […sequenceInputLayer(numFeatures) lstmLayer(numHiddenUnits) fullconnectedlayer (numResponses) regressionLayer];
指定培训选项。将求解器设置为“亚当”
和火车250个时代。为了防止梯度爆炸,将梯度阈值设置为1.指定初始学习速率0.005,并通过乘以0.2的因子来降低125个时期的学习速率。
选项=培训选项(“亚当”,…“MaxEpochs”,250,…'gradientthreshold',1,…“InitialLearnRate”, 0.005,…'shownrateschedule',“分段”,…“LearnRateDropPeriod”, 125,…“LearnRateDropFactor”, 0.2,…'verbose',0,…“阴谋”,“训练进步”);
使用指定的训练选项对LSTM网络进行训练trainNetwork
。
net = trainnetwork(xtrain,ytrain,图层,选项);
若要预测未来多个时间步长的值,请使用predictAndUpdateState
函数来预测时间步骤一次一个,并在每次预测时更新网络状态。对于每个预测,使用前一个预测作为函数的输入。
使用与训练数据相同的参数标准化测试数据。
dataTestStandardized = (dataTest - mu) / sig;XTest = dataTestStandardized (1: end-1);
为了初始化网络状态,首先对训练数据进行预测XTrain
。接下来,使用训练响应的最后一次步骤进行第一预测YTrain(结束)
。循环剩余预测并输入以前的预测predictAndUpdateState
。
对于大量数据、长序列或大型网络,GPU上的预测通常比CPU上的预测计算得更快。否则,对CPU的预测通常计算得更快。对于单时间步长预测,使用CPU。要使用CPU进行预测,请设置“ExecutionEnvironment”
选择predictAndUpdateState
来“cpu”
。
net = predictandanddattestate(net,xtrain);[net,ypred] = predictandanddattestate(net,ytrain(端));numtimestepstest = numel(xtest);为i = 2:numtimestepstest [net,ypred(:,i)] = predictandanddateState(net,ypred(:,i-1),“ExecutionEnvironment”,“cpu”);结束
利用前面计算的参数解开预测。
ypred = sig * ypred + mu;
培训进度绘图报告从标准化数据计算的根均方误差(RMSE)。从非标准化的预测计算RMSE。
欧美=人数((2:结束);rmse =√意味着(YPred-YTest)。^ 2))
rmse =单248.5531
绘制训练时间序列与预测值。
图绘图(DataTrain(1:终端1))保持上idx = numtimestepstrain :( numtimestepstrain + numtimestepstest);绘图(IDX,[数据(numtimestepstrain)ypred],“。”) 抓住离开Xlabel(“月”)ylabel(“案例”) 标题(“预测”) 传奇([“观察”“预测”])
将预测值与测试数据进行比较。
图形子图(2,1,1)绘图(ytest)保持上情节(YPred“。”) 抓住离开传奇([“观察”“预测”]) ylabel (“案例”) 标题(“预测”subplot(2,1,2) stem(YPred - YTest) xlabel(“月”)ylabel(“错误”) 标题(“rmse =”+ rmse)
如果您可以访问预测之间的时间步骤的实际值,则可以使用观察值而不是预测值更新网络状态。
首先,初始化网络状态。要对新序列进行预测,请使用该序列重置网络状态重置静止
。重置网络状态可防止以前的预测影响新数据上的预测。重置网络状态,然后通过预测训练数据来初始化网络状态。
net = ResetState(网络);net = predictandanddattestate(net,xtrain);
预测每个时间步。对于每一个预测,利用前一个时间步长的观测值预测下一个时间步长。设置“ExecutionEnvironment”
选择predictAndUpdateState
来“cpu”
。
Ypred = [];numtimestepstest = numel(xtest);为i = 1:numtimestepstest [net,ypred(:,i)] = predictandanddattestate(net,xtest(:,i),“ExecutionEnvironment”,“cpu”);结束
利用前面计算的参数解开预测。
ypred = sig * ypred + mu;
计算根均方误差(RMSE)。
rmse =√意味着(YPred-YTest)。^ 2))
RMSE = 158.0959.
将预测值与测试数据进行比较。
图形子图(2,1,1)绘图(ytest)保持上情节(YPred“。”) 抓住离开传奇([“观察”“预料到的”]) ylabel (“案例”) 标题(“通过更新预测”subplot(2,1,2) stem(YPred - YTest) xlabel(“月”)ylabel(“错误”) 标题(“rmse =”+ rmse)
这里,当使用观察到的值而不是预测值更新网络状态时,预测更准确。
lstmlayer.
|sequenceInputLayer
|培训选项
|trainNetwork