MATLAB深度学习:LSTM时间序列预测实战

摘要:

       此示例说明如何使用长短期记忆(LSTM)网络预测时间序列数据。为了预测序列的未来时间步长的值,可以训练一个序列到序列回归LSTM网络,其中的响应是值移动了一个时间步长的训练序列。也就是说,在输入序列的每个时间步长,LSTM网络学习预测下一个时间步长的值。要预测未来多个时间点的值,请使用forectAndUpdateState函数一次预测一个时间点,并在每次预测时更新网络状态。

cut-off

1、加载数据

       加载示例数据。某股票的收盘价,包含单个时间序列,时间步长为每日,值对应于每日收盘价。输出是一个单元数组,其中每个元素都是单个时间步长。将数据重塑为行矢量。

% 导入数据
clear,clc
data = importdata('out.txt');
data = data';
figure()
plot(data,LineWidth=2)

2、 数据拆分

         划分训练和测试数据。在序列的前90%进行训练,在最后10%进行测试。

% 定义测试与训练长度
numTimeStepsTrain = floor(0.9*numel(data));
dataTrain = data(1:numTimeStepsTrain+1);
dataTest = data(numTimeStepsTrain+1:end);

3、数据归一化

        为了更好地匹配和防止训练发散,将训练数据标准化为零均值和单位方差。在预测时,您必须使用与训练数据相同的参数来标准化测试数据。

% 训练数据归一化
mu = mean(dataTrain);
sig = std(dataTrain);

dataTrainStandardized = (dataTrain - mu) / sig;

       要预测序列的未来时间步长的值,请将响应指定为值移位一个时间步长的训练序列。也就是说,在输入序列的每个时间步长,LSTM网络学习预测下一个时间步长的值。

XTrain = dataTrainStandardized(1:end-1);
YTrain = dataTrainStandardized(2:end);

4、定义网络结构

        创建LSTM回归网络。将LSTM层指定为具有128个隐藏单元。训练参数可查看帮助,明白其中含义。

% 定义网络结构
layers = [
    sequenceInputLayer(1,"Name","input")
    lstmLayer(128,"Name","lstm")
%     dropoutLayer(0.2,"Name","drop")
    fullyConnectedLayer(1,"Name","fc")
    regressionLayer];
% 定义训练参数
options = trainingOptions('adam', ...
    'MaxEpochs',250, ...
    'GradientThreshold',1, ...
    'InitialLearnRate',0.005, ...
    'LearnRateSchedule','piecewise', ...
    'LearnRateDropPeriod',125, ...
    'LearnRateDropFactor',0.2, ...
    'Verbose',0, ...
    'Plots','training-progress');

5、训练网络

          使用TrainNetwork训练LSTM网络。

% 训练网络
net = trainNetwork(XTrain,YTrain,layers,options);

6、预测(使用预测值更新网络状态)

        要预测未来多个时间点的值,请使用forectAndUpdateState函数一次预测一个时间点,并在每次预测时更新网络状态。对于每个预测,使用先前的预测作为函数的输入。使用与训练数据相同的参数对测试数据进行标准化。

% 测试集归一化
dataTestStandardized = (dataTest - mu) / sig;
XTest = dataTestStandardized(1:end-1);
% 预测
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

        为了初始化网络状态,首先对训练数据XTrain进行预测。接下来,使用训练响应YTrain的最后一个时间步长进行第一个预测(完)。循环其余的预测,并将先前的预测输入到forectAndUpdateState。         对于大型数据集合、长序列或大型网络,在GPU上计算预测通常比在CPU上计算预测快。否则,在CPU上进行预测的计算速度通常会更快。对于单时间步长预测,请使用CPU。要使用CPU进行预测,请将recrectAndUpdateState的‘ExecutionEnvironment’选项设置为‘CPU’

        使用先前计算的参数来取消预测的标准化。

YPred = sig*YPred + mu;

         用预测值绘制训练时间序列。

% 绘图
figure
plot(dataTrain(1:end-1))
hold on
idx = numTimeStepsTrain:(numTimeStepsTrain+numTimeStepsTest);
plot(idx,[data(numTimeStepsTrain) YPred],'k.-'),hold on
plot(idx,data(numTimeStepsTrain:end-1),'r'),hold on
hold off
xlabel("Day")
ylabel("P")
title("Forecast")
legend(["Observed" "Forecast"])

7、预测(使用测试数据更新网络状态)

        如果您可以访问预测之间时间步长的实际值,则可以使用观测值而不是预测值来更新网络状态。首先,初始化网络状态。要对新序列进行预测,请使用Reset State重置网络状态。重置网络状态可防止先前的预测影响对新数据的预测。重置网络状态,然后通过对训练数据进行预测来初始化网络状态。

net = resetState(net);
net = predictAndUpdateState(net,XTrain);

         之后预测与6中基本一样,只不过用XTest中的数据更新网络状态

% 重置网络状态
net = resetState(net);
net = predictAndUpdateState(net,XTrain);
%

YPred = [];
numTimeStepsTest = numel(XTest);
for i = 1:numTimeStepsTest
    [net,YPred(:,i)] = predictAndUpdateState(net,XTest(:,i),'ExecutionEnvironment','cpu');
end

YPred = sig*YPred + mu;

% 绘图
figure
plot(dataTrain(1:end-1))
hold on
idx = numTimeStepsTrain:(numTimeStepsTrain+numTimeStepsTest);
plot(idx,[data(numTimeStepsTrain) YPred],'k.-'),hold on
plot(idx,data(numTimeStepsTrain:end-1),'r'),hold on
hold off
xlabel("Day")
ylabel("P")
title("Forecast")
legend(["Observed" "Forecast"])

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空