本次运行测试环境MATLAB2020b;
文章针对LSTM 存在的局限性,提出了将Attention机制结合LSTM 神经网络的预测模型。采用多输入单输出回归预测,再将attention 机制与LSTM 结合作为预测模型,使预测模型增强了对关键时间序列的注意力。
%% Attention_LSTM
% 数据集,列为特征,行为样本数目
clc
clear
close all
% 导入数据
load('./data.mat')
data(1,:) =[];
% 训练集
y = data.demand(1:1000);
x = data{1:1000,3:end};
[xnorm,xopt] = mapminmax(x',0,1);
[ynorm,yopt] = mapminmax(y',0,1);
x = x';
xnorm = xnorm(:,1:1000);
ynorm = ynorm(1:1000);
% 滞后长度
k = 24;
% 转换成2-D image
for i = 1:length(ynorm)-k
Train_xNorm(:,i,:) = xnorm(:,i:i+k-1);
Train_yNorm(i) = ynorm(i+k-1);
end
Train_yNorm= Train_yNorm';
% 测试集
ytest = data.demand(1001:1170);
xtest = data{1001:1170,3:end};
[xtestnorm] = mapminmax('apply', xtest',xopt);
[ytestnorm] = mapminmax('apply',ytest',yopt);
xtest = xtest';
for i = 1:length(ytestnorm)-k
Test_xNorm(:,i,:) = xtestnorm(:,i:i+k-1);
Test_yNorm(i) = ytestnorm(i+k-1);
Test_y(i) = ytest(i+k-1);
end
Test_yNorm = Test_yNorm';
clear k i x y
% 自定义训练循环的深度学习数组
Train_xNorm = dlarray(Train_xNorm,'CBT');
Train_yNorm = dlarray(Train_yNorm,'BC');
Test_xNorm = dlarray(Test_xNorm,'CBT');
Test_yNorm = dlarray(Test_yNorm,'BC');
% 训练集和验证集划分
TrainSampleLength = length(Train_yNorm);
validatasize = floor(TrainSampleLength * 0.1);
Validata_xNorm = Train_xNorm(:,end - validatasize:end,:);
Validata_yNorm = Train_yNorm(:,end-validatasize:end,:);
Train_xNorm = Train_xNorm(:,1:end-validatasize,:);
Train_yNorm = Train_yNorm(:,1:end-validatasize,:);
%% 参数设定
%数据输入x的特征维度
inputSize = size(Train_xNorm,1);
%数据输出y的维度
outputSize = 1;
numhidden_units=50;
% 导入初始化参数
[params,~] = paramsInit(numhidden_units,inputSize,outputSize);
[~,validatastate] = paramsInit(numhidden_units,inputSize,outputSize);
[~,TestState] = paramsInit(numhidden_units,inputSize,outputSize);
% 训练相关参数
TrainOptions;
numIterationsPerEpoch = floor((TrainSampleLength-validatasize)/minibatchsize);
LearnRate = 0.01;
%% 迭代更新
figure
start = tic;
lineLossTrain = animatedline('color','b');
validationLoss = animatedline('color','r','Marker','o');
xlabel("Iteration")
ylabel("Loss")
% epoch 更新
iteration = 0;
for epoch = 1 : numEpochs
[~,state] = paramsInit(numhidden_units,inputSize,outputSize); % 每轮epoch,state初始化
disp(['Epoch: ', int2str(epoch)])
% batch 更新
for i = 1 : numIterationsPerEpoch
iteration = iteration + 1;
disp(['Iteration: ', int2str(iteration)])
idx = (i-1)*minibatchsize+1:i*minibatchsize;
dlX = gpuArray(Train_xNorm(:,idx,:));
dlY = gpuArray(Train_yNorm(idx));
[gradients,loss,state] = dlfeval(@ModelD,dlX,dlY,params,state);
% L2正则化
L2regulationFactor = 0.001;
[params,averageGrad,averageSqGrad] = adamupdate(params,gradients,averageGrad,averageSqGrad,iteration,LearnRate);
% 验证集测试
if iteration == 1 || mod(iteration,validationFrequency) == 0
output_Ynorm = ModelPredict(gpuArray(Validata_xNorm),params,validatastate);
lossValidation = mse(output_Ynorm, gpuArray(Validata_yNorm));
end
% 作图(训练过程损失图)
D = duration(0,0,toc(start),'Format','hh:mm:ss');
addpoints(lineLossTrain,iteration,double(gather(extractdata(loss))))
if iteration == 1 || mod(iteration,validationFrequency) == 0
addpoints(validationLoss,iteration,double(gather(extractdata(lossValidation))))
end
title("Epoch: " + epoch + ", Elapsed: " + string(D))
legend('训练集','验证集')
drawnow
end
% 每轮epoch 更新学习率
if mod(epoch,10) == 0
LearnRate = LearnRate * LearnRateDropFactor;
end
end
[1] https://mianbaoduo.com/o/bread/mbd-YZ2clJ5x
[2] https://blog.csdn.net/kjm13182345320/article/details/120406657?spm=1001.2014.3001.5501
[3] https://blog.csdn.net/kjm13182345320/article/details/120377303?spm=1001.2014.3001.5501