【MATLAB】构建LSTM网络来做时间预测,采用多输入单输出模式,具体看代码。
现在我遇到的问题是,模型训练好以后,把测试集和训练集放进去做预测,得到的输出与训练集输出、测试集输出拟合都很好,但是我再用网络去做多步预测,结果非常糟糕,基本上只能预测正确一个数,麻烦各位老哥看看,到底该怎么修改代码。
result = xlsread('summation.xlsx');
Result1 = result(:,2);
mu = mean(Result1);
sig = std(Result1);
result1 = (Result1 - mu) / sig;
num_samples1 = length(result1 ); % 样本个数
kim = 15; % 步长
zim = 1; % 预测量
res1 = zeros(24985,16);
for i = 1: num_samples1 - kim - zim + 1
res1(i, :) = [reshape(result1(i: i + kim - 1), 1, kim),...
result1(i + kim + zim - 1)];
end
temp1 = 1: 1: 24985;a1 = 19988; b1 = 19989;
XTrain1 = res1(temp1(1:a1) ,1:15)';% 训练集输入
YTrain1 = res1(temp1(1:a1) ,16 )';% 训练集输出
XTest1 = res1(temp1(b1:end),1:15)';% 测试集输入
YTest1 = res1(temp1(b1:end),16 )';% 测试集输出
XTrain = XTrain1;YTrain = YTrain1;
XTest = XTest1 ;YTest = YTest1;
M = size(XTrain,2); N = size(XTest,2);
XTrain = double(reshape(XTrain, 15, 1, 1, M));
XTest = double(reshape(XTest , 15, 1, 1, N));
yTrain = YTrain';
yTest = YTest' ;
xtrain = cell(M,1);
for i = 1 : M
xtrain{i, 1} = XTrain(:, :, 1, i);
end
xtest = cell(N,1);
for i = 1 : N
xtest{i, 1} = XTest( :, :, 1, i);
end
layers = [
sequenceInputLayer(15) % 建立输入层
lstmLayer(20, 'OutputMode', 'last') % LSTM层
reluLayer % Relu激活层
fullyConnectedLayer(1) % 全连接层
regressionLayer]; % 回归层
options = trainingOptions('adam', ... % Adam 梯度下降算法
'MaxEpochs', 800, ... % 最大训练次数
'InitialLearnRate', 5e-3, ... % 初始学习率
'LearnRateSchedule', 'piecewise', ... % 学习率下降
'LearnRateDropFactor', 0.1, ... % 学习率下降因子
'LearnRateDropPeriod', 800, ... % 经过20000次训练后 学习率为 0.005 * 0.1
'Shuffle', 'every-epoch', ... % 每次训练打乱数据集
'Plots', 'training-progress', ... % 画出曲线
'Verbose', false);
net = trainNetwork(xtrain, yTrain, layers, options);
net = predictAndUpdateState(net,xtrain);
net = resetState(net);
t_sim1 = predict(net, xtrain);
t_sim2 = predict(net, xtest );
T_sim1 = sig*t_sim1 + mu;
T_sim2 = sig*t_sim2 + mu;
YTrain11 = sig*YTrain1 + mu;
YTest11 = sig*YTest1 + mu;
figure
plot(1: M, YTrain11, 'r-', 1: M, T_sim1, 'b-', 'LineWidth', 1)
legend('真实值', '预测值')
xlabel('预测样本')
ylabel('预测结果')
xlim([1, M])
grid
figure
plot(1: N, YTest11, 'r-', 1: N, T_sim2, 'b-', 'LineWidth', 1)
legend('真实值', '预测值')
xlabel('预测样本')
ylabel('预测结果')
xlim([1, N])
grid
训练集预测
测试集预测
多步预测
多步预测结果很糟糕。我代码到底哪错了,模型调参我感觉应该不需要。
有多方面的原因,可能要自己一步步检查下。比如数据集的问题,数据集可能不够充足或者不够多样化,导致网络无法有效地学习到长期的时间模式。或者LSTM网络结构可能不够合适,可以考虑调整网络层数、神经元数量、激活函数等参数来优化网络性能。可以尝试增加训练次数或者使用更复杂的优化算法来优化训练过程。另外,注意选择适当的损失函数和评价指标。
可能是数据集不够充足、不够多样化导致的
增加数据集试试
基于new bing部分指引作答:
根据你提供的代码,我注意到你在进行多步预测时只是简单地使用了一次predict函数来进行预测。然而,LSTM网络在多步预测时需要逐步迭代预测结果,将前一步的预测结果作为输入来预测下一步。
下面是你需要修改的代码部分,以实现多步预测:
net = predictAndUpdateState(net, xtrain);
net = resetState(net);
% 多步预测
numSteps = size(xtest, 1); % 测试集输入的时间步数
t_sim2 = zeros(numSteps, 1);
x = xtrain{end}; % 使用最后一个训练样本作为初始输入
for i = 1:numSteps
t_pred = predict(net, x); % 预测下一步
t_sim2(i) = sig * t_pred + mu; % 保存预测结果
x = [x(2:end); t_pred]; % 更新输入,去掉第一个值,加入预测值
end
上述代码将使用训练集的最后一个样本作为初始输入,在每个时间步进行预测,并将预测结果保存在t_sim2中。请注意,我修改了xtest为xtrain,因为在多步预测时需要使用训练集的数据来生成预测序列。
接下来,你可以使用修改后的代码重新运行多步预测部分,并查看结果是否有所改善。希望这可以解决你的问题!
要检查网络并查看层的详细信息,请点击分析。