刚接触LSTM,问题困扰了我很久,麻烦各位帮忙看下,快给整自闭了
%% 定义训练集与测试集
[m,n]=size(Initialdata);
zoom = 1000; %缩放数据集
n = floor(n/zoom);
data = zeros(1,n);
for i = 1:n
data(1,i) = Initialdata(1,i*zoom);
end
n1=round(n*0.5); %划分数据集
dataTrain = data(1:n1); %定义训练集
dataTest = data(:,n1+1:n); %该数据是用来在最后与预测值进行对比的
%% 数据预处理
mu = mean(dataTrain); %求均值
sig = std(dataTrain); %求均差
dataTrainStandardized = (dataTrain - mu) / sig; %求单位标准差
%% 构建滑动窗口
step = 2; % 步长
pre = 5000; %对未来预测的步数
XTrain = zeros(step,n1-step);
count = 1;
XTrainColumn = 1; % 标志XTrain中的当前存储列数
for r = 1:n1-step
for h = 1:step
XTrain(count,XTrainColumn) = dataTrainStandardized(r+h-1);
count = count + 1;
end
XTrainColumn = XTrainColumn + 1; % 一次滑窗结束后,当前存储行数、count位、滑窗的开始结束位置都发生改变
count = 1;
end
YTrain = dataTrainStandardized(step+1:end);
%% 建立LSTM
numFeatures = step; %特征维度与滑动窗口大小一致
numResponses = 1; %输出为一维
numHiddenUnits = 10; %创建LSTM回归网络,指定LSTM层的隐含单元个数。可调
layers = [
sequenceInputLayer(numFeatures,"Normalization","zscore")
lstmLayer(3)
dropoutLayer(0.9)
fullyConnectedLayer(numResponses)
regressionLayer]; % 回归输出
options = trainingOptions('adam', ... %求解器设置为adam
'MaxEpochs',300, ... %训练轮数
'GradientThreshold',1, ... %梯度阈值
'InitialLearnRate',0.05, ... %指定初始学习率
'LearnRateSchedule','piecewise', ... %每当经过一定数量的时期时,学习率就会乘以一个系数。
'LearnRateDropPeriod',1000, ... %乘法之间的纪元数由“ LearnRateDropPeriod”控制。可调
'LearnRateDropFactor',0.5, ... %乘法因子由参“ LearnRateDropFactor”控制,可调。在 LearnRateDropPeriod 轮训练后通过乘以因子 LearnRateDropFactor 来降低学习率
'Verbose',0, ... %如果将其设置为true,则有关训练进度的信息将被打印到命令窗口中。默认值为true
'Plots','training-progress'); %构建曲线图。关闭则将'training-progress'替换为none
net = trainNetwork(XTrain,YTrain,layers,options); %使用以上LSTM参数对指定训练集进行训练
%% 进行用于验证神经网络的数据预测(用预测值更新网络状态)
net = predictAndUpdateState(net,XTrain);
for i = 1 : n1-step
x=XTrain(:,i);
[net,y] = predictAndUpdateState(net,x,'MiniBatchSize',1); %YPlot为LSTM训练集所得参数
YPlot(:,i)=y;
end
count = 1;
for i = 1: step
XTrain(i,n1-step+1) = dataTrainStandardized(:,n1-step+i);
end
for r=1:n-n1+pre
for h = 1:step-1
XTrain(count,n1-step+r+1) = XTrain(count+1,n1-step+r);
count = count + 1;
end
x=XTrain(:,n1-step+r);
[net,y] = predictAndUpdateState(net,x,'MiniBatchSize',1);
YPlot(:,n1-step+r)=y;
XTrain(count,n1-step+r+1) = YPlot(:,n1-step+r);
count = 1;
end
%% 验证神经网络
YPlot = sig*YPlot + mu; %使用先前计算的参数对预测去标准化。
rmse = sqrt(mean((YPlot(n1-step+1:end-pre)-dataTest).^2)) ; %计算均方根误差 (RMSE)。
subplot(2,1,1)
plot(YPlot(1:n1-step)) %画出训练数据
hold on
idx = n1+1:n; %横坐标
plot(idx,YPlot(n1-step+1:end-pre),'.-') %显示预测值
hold off
xlabel("Time")
ylabel("Case")
title("Forecast")
legend(["Observed" "Forecast"])
subplot(2,1,2)
plot(data)
xlabel("Time")
ylabel("Case")
title("Dataset")
Observed是训练集经过LSTM拟合得到的,Forecast是用上一个时间步长的LSTM输出作为新输入得到的
可以尝试增加LSTM层的隐含单元个数numHiddenUnits,或者调整学习率看看