长短期记忆网络(LSTM)


LSTM的使用场景

1、基于LSTM的数据回归预测

数据回归预测一般应用在不考虑时间的场景中,只是简单的将拥有的数据分为输入及输出两类,之后将输入与输出划分为测试集与训练集,用训练集去训练模型,测试集检验模型性能,简单例子如下:

% 导入数据
res = readmatrix("数据.xlsx");

%% 划分训练集和测试集
temp = randperm(80);%数据回归预测中不考虑时间,故可将测试数据进行乱序
P_train = res(temp(1:60),1:7)';
T_train = res(temp(1:60),8)';
M = size(P_train,2);%size(A,1)返回A矩阵列数,size(A,2)返回A矩阵行数

P_test = res(temp(61:end),1:7)';
T_test = res(temp(61:end),8)';
N = size(P_test,2);

%% 数据归一化
[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);

%% 数据平铺
P_train = double(reshape(P_train,7,1,1,M));
P_test = double(reshape(P_test,7,1,1,N));

t_train = t_train';
t_test = t_test';

%% 数据格式转换
for i = 1:M
    p_train{i,1} = P_train(:,:,1,i);
end

for i = 1:N
    p_test{i,1} = P_test(:,:,1,i);
end

%% 创建模型
layers = [
    sequenceInputLayer(7)%建立输入层
    
    lstmLayer(4,'OutputMode','last')%LSTM层
    reluLayer %relu激活层
    
    fullyConnectedLayer(1)
    regressionLayer];

%% 参数设置
options = trainingOptions('adam', ...
    'MiniBatchSize', 30, ...
    'MaxEpochs', 1200, ...
    'InitialLearnRate', 1e-2, ...
    'LearnRateSchedule', 'piecewise', ...
    'LearnRateDropFactor', 0.5, ...
    'LearnRateDropPeriod', 800, ...
    'Plots','training-progress',...
    'Verbose',false);

%% 训练模型
net = trainNetwork(p_train,t_train,layers,options);

%% 仿真预测
t_sim1 = predict(net,p_train);
t_sim2 = predict(net,p_test);

%% 数据反归一化
T_sim1 = mapminmax('reverse',t_sim1,ps_output);
T_sim2 = mapminmax('reverse',t_sim2,ps_output);

%% 均方根误差
error1 = sqrt(sum((T_sim1'-T_train).^2)./M);
error2 = sqrt(sum((T_sim2'-T_test).^2)./N);

%% 查看网络结构
analyzeNetwork(net)

%% 绘图
T = [T_train,T_test];
S = [T_sim1',T_sim2'];
figure
plot(1:80,T,1:80,S,'LineWidth',1);
legend('真实值','预测值')
xlabel('Time')
ylabel('Value')
title('5mm2550热电偶基于LSTM模型的数据预测')
grid

2、基于LSTM的数据分类预测

主要用于对一组数据的类别进行预测。此类情况与数据回归预测的区别在于此类情况的输出是固定的类别名或类别值,而不是一个存粹的数值。注意,在数据归一化时需要用到categorical函数,简单例子如下。

% 导入数据
res = readmatrix("数据.xlsx");

%% 划分训练集和测试集
temp = randperm(357);%数据回归预测中不考虑时间,故可将测试数据进行乱序
P_train = res(temp(1:240),1:12)';
T_train = res(temp(1:240),13)';
M = size(P_train,2);%size(A,1)返回A矩阵列数,size(A,2)返回A矩阵行数

P_test = res(temp(241:end),1:12)';
T_test = res(temp(241:end),13)';
N = size(P_test,2);

%% 数据归一化
[P_train,ps_input] = mapminmax(P_train,0,1);
P_test = mapminmax('apply',P_test,ps_input);

t_train = categorical(T_train)';
t_test = categorical(T_test)';

%% 数据平铺
P_train = double(reshape(P_train,12,1,1,M));
P_test = double(reshape(P_test,12,1,1,N));

t_train = t_train';
t_test = t_test';

%% 数据格式转换
for i = 1:M
    p_train{i,1} = P_train(:,:,1,i);
end

for i = 1:N
    p_test{i,1} = P_test(:,:,1,i);
end

%% 创建模型
layers = [
    sequenceInputLayer(12)              %建立输入层
    
    lstmLayer(6,'OutputMode','last')    %LSTM层
    reluLayer                           %relu激活层
    
    fullyConnectedLayer(4)              %全连接层
    softmaxLayer                        %分类层
    classificationLayer];               

%% 参数设置
options = trainingOptions('adam', ...       %adam梯度下降算法
    'MiniBatchSize', 100, ...               %批大小
    'MaxEpochs', 1000, ...                  %最大迭代次数
    'InitialLearnRate', 1e-2, ...           %初始学习率
    'LearnRateSchedule', 'piecewise', ...   %学习率下降
    'LearnRateDropFactor', 0.1, ...         %学习率下降因子
    'LearnRateDropPeriod', 700, ...         %经过700次训练后,学习率为0.01*0.1
    'Shuffle','every-epoch',...             %每次训练打乱数据集
    'ValidationPatience',Inf,...            %关闭验证
    'Plots','training-progress',...         %画出曲线
    'Verbose',false);                       

%% 训练模型
net = trainNetwork(p_train,t_train,layers,options);

%% 仿真预测
t_sim1 = predict(net,p_train);
t_sim2 = predict(net,p_test);

%% 数据反归一化
T_sim1 = vec2ind(t_sim1);
T_sim2 = vec2ind(t_sim2);

%% 性能
error1 = sum((T_sim1 == T_train)) / M * 100;
error2 = sum((T_sim2 == T_test)) / N *100;

%% 查看网络结构
analyzeNetwork(net)

%% 数据排序
[T_train,index_1] = sort(T_train);
[T_test,index_2] = sort(T_test);

T_sim1 = T_sim1(index_1);
T_sim2 = T_sim2(index_2);

%% 绘图
figure
plot(1:M,T_train,'r-*',1:M,T_sim1,'b-o','LineWidth',1);
legend('真实值','预测值')
xlabel('预测样本')
ylabel('预测结果')
string = {'测试集预测集结果对比';['准确率=' num2str(error2) '%']};
title(string)
xlim([1,N])
grid

%% 混淆矩阵
figure
cm = confusionchart(T_train,T_sim1);
cm.Title = 'Confusion Matrix for Train Data';
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';

figure
cm = confusionchart(T_test,T_sim2);
cm.Title = 'Confusion Matrix for Test Data';
cm.ColumnSummary = 'column-normalized';
cm.RowSummary = 'row-normalized';

3、 基于LSTM的时间序列预测

一般用于对与时间有关的数据序列进行预测,例如股票预测,温度预测等。方式:可将时间序列预测转换成数据回归预测,例如,将时间序列预测转换成通过前15个数据预测第16个数据,通过第2-16个数据预测第17个数据,以此类推。简单例子如下。

data = readmatrix("数据.xlsx");

%% 
% 数据分析
num_samples = length(data);
kim = 15;
zim = 1;

% 划分数据集
for i = 1:num_samples-kim-zim+1
    res(i,:) = [reshape(data(i:i+kim-1),1,kim),data(i+kim+zim-1)];
end

% 划分训练集和测试集
temp = 1:1:5485;
P_train = res(temp(1:4400),1:15)';
T_train = res(temp(1:4400),16)';
M = size(P_train,2);

P_test = res(temp(4401:end),1:15)';
T_test = res(temp(4401:end),16)';
N = size(P_test,2);

%数据归一化
[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);

% 数据平铺
P_train = double(reshape(P_train,15,1,1,M));
P_test = double(reshape(P_test,15,1,1,N));

t_train = t_train';
t_test = t_test';

% 数据格式转换
for i = 1:M
    p_train{i,1} = P_train(:,:,1,i);
end

for i = 1:N
    p_test{i,1} = P_test(:,:,1,i);
end

% 创建模型
layers = [
    sequenceInputLayer(15)
    
    lstmLayer(10,'OutputMode','last')
    reluLayer
    
    fullyConnectedLayer(1)
    regressionLayer];

% 参数设置
options = trainingOptions('adam', ...
    'MiniBatchSize', 2000, ...
    'MaxEpochs', 800, ...
    'InitialLearnRate', 1e-2, ...
    'LearnRateSchedule', 'piecewise', ...
    'LearnRateDropFactor', 0.5, ...
    'LearnRateDropPeriod', 800, ...
    'Plots','training-progress',...
    'Verbose',false);

% 训练模型
net = trainNetwork(p_train,t_train,layers,options);

% 仿真预测
t_sim1 = predict(net,p_train);
t_sim2 = predict(net,p_test);

% 数据反归一化
T_sim1 = mapminmax('reverse',t_sim1,ps_output);
T_sim2 = mapminmax('reverse',t_sim2,ps_output);

% 均方根误差
error1 = sqrt(sum((T_sim1'-T_train).^2)./M);
error2 = sqrt(sum((T_sim2'-T_test).^2)./N);

% 查看网络结构
analyzeNetwork(net)

% 绘图
T = [T_train,T_test];
S = [T_sim1',T_sim2'];
figure
plot(1:5485,T,1:5485,S,'LineWidth',1);
legend('真实值','预测值')
xlabel('Time')
ylabel('Value')
title('4mm1525红外基于LSTM模型的数据预测')
text(200,170,"error1:"+error1)
text(200,163,"error2:"+error2)
grid
% 4mm1525
Ppid = zeros(1,5500);
for t=1:1:1000
    Ppid(t)=15;
end
for t=1000:1:2000
    Ppid(t)=25;
end
for t=2000:1:3000
    Ppid(t)=15;
end
for t=3000:1:4000
    Ppid(t)=25;
end
for t=4000:1:5500
    Ppid(t)=15;
end
Ppid = Ppid';

%% 热电偶单个预测
xlsx = readmatrix("../数据/4mm1525热电偶.xlsx");
data = zeros(1,5500);
data(1) = xlsx(1);
a = (xlsx(2)-xlsx(1))/99;
i=2;
for t=2:1:5500
    if mod(t,99)==0
        i = i+1;
        a = (xlsx(i)-xlsx(i-1))/99;
    end
    data(t) = data(t-1)+a;
end

% 红外单个预测
data = readmatrix("../数据/4mm1525红外.xlsx");
data = data';

%% 数据拆分
numTimeStepsTrain = floor(0.8*numel(data));
dataTrain = data(1:numTimeStepsTrain+1);
dataTest = data(numTimeStepsTrain+1:end);

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

dataTrainStandardized = (dataTrain - mu) / sig;
XTrain = dataTrainStandardized(1:end-1);
YTrain = dataTrainStandardized(2:end);

%% 定义网络结构
layers = [
    sequenceInputLayer(1,"Name","input")
    lstmLayer(128,"Name","lstm")
    dropoutLayer(0.2,"Name","drop")
    fullyConnectedLayer(1,"Name","fc")
    regressionLayer];

%% 定义训练参数
options = trainingOptions('adam',...
    'MaxEpochs',150,...
    'GradientThreshold',1,...
    'InitialLearnRate',0.005,...
    'LearnRateSchedule','piecewise',...
    'LearnRateDropPeriod',125,...
    'LearnRateDropFactor',0.2,...
    'Verbose',0,...
    'Plots','training-progress')

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

%% 测试集归一化
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

%% 反归一化
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"])

%% 重置网络
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"])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值