LSTM(Long Short-Term Memory,长短期记忆网络)是一种特殊类型的递归神经网络(RNN),专门用于处理和预测基于时间序列的数据。与传统RNN相比,LSTM在处理长期依赖问题时具有显著优势。
LSTM的基本结构
LSTM由一个称为“细胞状态”(cell state)的核心组件和三个门(gate)组成。这些门控制着信息的流入、流出和保留,从而应对长时间依赖问题。这三个门分别是:
输入门(Input Gate):决定有多少新信息将被存储在细胞状态中。
遗忘门(Forget Gate):决定细胞状态中的哪些信息将被丢弃。
输出门(Output Gate):决定从细胞状态中输出多少信息。
LSTM的应用
LSTM因其在处理序列数据上的强大能力,被广泛应用于各种领域,如:
自然语言处理(NLP)
语音识别
时间序列预测
图像描述生成
LSTM通过巧妙设计的门机制,有效地解决了传统RNN在长时间序列数据上容易产生梯度消失或梯度爆炸的问题,从而在许多实际应用中表现出色。
LSTM的MATLAB实现
%% 清空环境变量
clc;
clear;
close all;
warning off;
tic
%% 导入数据
load testdata.mat;
%% 数据分析
[trainInd,valInd,testInd] = dividerand(size(X,2),0.7,0,0.3); %划分训练集与测试集
P_train = X(:,trainInd); %列索引
T_train = Y(:,trainInd);
P_test = X(:,testInd);
T_test = Y(:,testInd);
M = size(P_train, 2);
N = size(P_test, 2);
L = size(P_train, 1);
lstmnumber = 50;
%% 数据归一化
[p_train, ps_input] = mapminmax(P_train, 0, 1);
p_test = mapminmax('apply', P_test, ps_input);
[t_train, ps_output] = mapminmax(T_train, 0, 1);
t_test = mapminmax('apply', T_test, ps_output);
%% 数据平铺
%将数据平铺成1维数据只是一种处理方式
%也可以平铺成2维数据,以及3维数据,需要修改对应模型结构
%但是应该始终和输入层数据结构保持一致
p_train = double(reshape(p_train, L, 1, 1, M));
p_test = double(reshape(p_test , L, 1, 1, N));
t_train = double(t_train)';
t_test = double(t_test )';
%% 数据格式转换
for i = 1 : M
Lp_train{i, 1} = p_train(:, :, 1, i);
end
for i = 1 : N
Lp_test{i, 1} = p_test( :, :, 1, i);
end
%% 建立模型
layers = [
sequenceInputLayer([L, 1, 1], "Name", "sequence") % 建立输入层,输入数据结构为[f_, 1, 1]
flattenLayer("Name", "flatten") % 网络铺平层
lstmLayer(lstmnumber,'Name','lstm1',"OutputMode", "last") % lstm层
fullyConnectedLayer(1, "Name", "fc") % 全连接层
regressionLayer
]; % 回归层
%% 参数设置
options = trainingOptions('adam', ... % Adam 梯度下降算法
'MaxEpochs', 200, ... % 最大迭代次数
'GradientThreshold',1,...
'InitialLearnRate', 1e-3, ... % 初始学习率为0.01
"L2Regularization",1e-4,...
'LearnRateSchedule', 'piecewise', ... % 学习率下降
'LearnRateDropFactor', 0.1, ... % 学习率下降因子 0.5
'LearnRateDropPeriod', 190, ... % 经过190次训练后 学习率为 0.01 * 0.1
'Shuffle', 'every-epoch', ... % 每次训练打乱数据集
"Plots","training-progress",...
'Verbose',false);
%% 训练模型
net = trainNetwork(Lp_train, t_train, layers, options);
analyzeNetwork(layers)
%% 模型预测
t_sim = net.predict(Lp_test);
T_sim = mapminmax('reverse',t_sim,ps_output);
T_sim = double(T_sim);
%% 评价指标
% 误差 error
error = T_test - T_sim';
% 平均绝对误差MAE
MAE = mean(abs(T_sim' - T_test));
% 平均绝对百分比误差MAPE
MAPE = mean(abs((T_test - T_sim')./T_test));
% 均方根误差RMSE
RMSE = sqrt(sum((T_test - T_sim').^2)./N);
% 均方误差MSE
MSE = sum((T_test - T_sim' ).^2)./N;
% 决定系数R2
R = 1 - norm(T_test - T_sim')^2 / norm(T_test - mean(T_test ))^2;
%% 绘图
figure(1)
plotregression(T_test,T_sim',['回归图']);
figure(2)
ploterrhist(T_test-T_sim',['误差直方图']);
figure(3)
plot(T_test)
hold on
plot(T_sim)
hold on
xlabel('t/s')
ylabel('value')
title('LSTM预测结果')
legend({'预测间隔','实际值','预测值'})
figure(4)
plot(error);
xlabel('t/s')
ylabel('err')
title('LSTM预测误差')
%% 打印出评价指标
disp(['-----------------------误差计算--------------------------'])
disp(['评价结果如下所示:'])
disp(['平均绝对误差MAE为: ',num2str(MAE)])
disp(['平均绝对百分比误差MAPE为: ',num2str(MAPE)])
disp(['均方误差MSE为: ',num2str(MSE)])
disp(['均方根误差RMSE为: ',num2str(RMSE)])
disp(['决定系数R^2为: ',num2str(R)])
toc
预测结果