1.31、基于长短记忆网络(LSTM)的发动机剩余寿命预测(matlab)
1、基于长短记忆网络(LSTM)的发动机剩余寿命预测的原理及流程
基于长短期记忆网络(LSTM)模型的发动机剩余寿命预测是一种典型的机器学习应用实例。该方法旨在分析并预判发动机或其他工业设备在运行过程中的剩余使用寿命。以下部分将介绍LSTM在发动机余存 lifespan 预测中的工作原理及其实施流程:
基于长短期记忆网络(LSTM)模型的发动机剩余寿命预测是一种典型的机器学习应用实例。该方法旨在分析并预判发动机或其他工业设备在运行过程中的剩余使用寿命。以下部分将介绍LSTM在发动机余存 lifespan 预测中的工作原理及其实施流程:
数据收集: 首要任务是获取发动机的关键参数数据。具体而言,则需要采集温度、压力、振动等关键参数,并整合与发动机维护相关的记录信息。
数据预处理: 从收集的数据中进行去杂、降噪、特征提取等必要的预处理工作,并为后续模型训练提供高质量的数据支持。同时对数据按照时间顺序进行排序处理,以确保构建出完整的时序数据集。
构建LSTM模型: 借助主流深度学习框架中的工具库(如TensorFlow、Keras等),开发一种基于长短期记忆单元的神经网络架构。该模型结构能够有效地处理时间序列数据,并通过识别其中的长期关联性,在序列数据预测任务中展现出优异的性能表现。
数据划分的标准: 按照标准将给定的数据集合分为训练子集和测试子集。其中训练子集中存储着用于模型训练的基础数据;而测试子集中则包含了需要进行预测的样本数据。
模型训练: 基于训练数据集对LSTM网络进行训练,并通过动态调整模型参数以提高预测准确性。经过迭代优化后,在数据学习过程中使得该网络能够有效地识别并建模数据中的特征与关系。
模型预测:
测定模型效能: 通过对比实际剩余寿命数据的结果作为基准,测定模型效能的具体表现;常用指标包括均方根误差(RMSE)等来衡量预测精度。
预测与优化: 根据模型的预测结果,请制定相应的维护计划并采取预防措施来减少发动机故障的发生并提升设备的工作寿命。同时,请持续改进LSTM模型以便提高其预测精度和可靠性。
按照以下步骤进行操作:首先建立完整的机器学习模型训练集;其次设计高效的特征提取方法;最后应用循环神经网络算法构建RUL预测模型。利用该模型可以帮助企业在实际生产中实现精准的 Remaining Useful Life 预测,并为企业制定相应的健康管理策略提供数据支持。
2、基于长短记忆网络(LSTM)的发动机剩余寿命预测说明
使用长短记忆网络(LSTM)依据时间序列数据预测发动机的剩余使用寿命
3、数据集处理
1)说明
创建一个目录来存储涡轮风扇发动机退化仿真数据集
2)代码
dataFolder = fullfile(tempdir,"turbofan");
if ~exist(dataFolder,"dir")
mkdir(dataFolder);
end
4、准备训练数据
1)提取数据
实现代码
filenamePredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,TTrain] = processTurboFanDataTrain(filenamePredictors);
2)删除具有常量值的特征
实现代码
XTrainConcatenatedTimesteps = cat(1,XTrain{:});
m = min(XTrainConcatenatedTimesteps,[],1);
M = max(XTrainConcatenatedTimesteps,[],1);
idxConstant = M == m;
for i = 1:numel(XTrain)
XTrain{i}(:,idxConstant) = [];
end
3)查看序列中其余特征的数量
实现代码
numFeatures = size(XTrain{1},2)
4)归一化训练预测变量
将训练预测变量归一化为具有零均值和单位方差。
实现代码
XTrainConcatenatedTimesteps = cat(1,XTrain{:});
mu = mean(XTrainConcatenatedTimesteps,1);
sig = std(XTrainConcatenatedTimesteps,0,1);
for i = 1:numel(XTrain)
XTrain{i} = (XTrain{i} - mu) ./ sig;
end
5)裁剪响应
通过大量从发动机即将出现故障时的时间序列数据进行训练,并设置响应的裁剪阈值为150。这将导致网络将具有更高剩余使用寿命(RUL)的实例识别为相同。
实现代码
thr = 150;
for i = 1:numel(TTrain)
TTrain{i}(TTrain{i} > thr) = thr;
end
视图效果

6)准备要填充的数据
均匀划分训练数据的小批量大小,并减少小批量中的填充量
按序列长度对训练数据进行排序
实现代码
for i=1:numel(XTrain)
sequence = XTrain{i};
sequenceLengths(i) = size(sequence,1);
end
[sequenceLengths,idx] = sort(sequenceLengths,"descend");
XTrain = XTrain(idx);
TTrain = TTrain(idx);
7)查看排序的序列长度
实现代码
figure
bar(sequenceLengths)
xlabel("Sequence")
ylabel("Length")
title("Sorted Data")
视图效果


5、定义网络架构
1)创建网络
构建一个 LSTM 神经网络模型。该模型包含一个拥有 200 个隐藏神经元的 LSTM 层;接着是一个输出维度为50的线性变换层;最后配置了一个丢弃率设置为50%的丢弃层。
实现代码
numResponses = size(TTrain{1},2);
numHiddenUnits = 200;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,OutputMode="sequence")
fullyConnectedLayer(50)
dropoutLayer(0.5)
fullyConnectedLayer(numResponses)];
2)指定训练选项
使用求解器 "adam" 以大小为 20 的小批量进行 60 轮训练。
指定学习率为 0.01。防止梯度爆炸,将梯度阈值设置为 1。
使序列保持按长度排序,将 Shuffle 选项设置为 "never"。
实现代码
maxEpochs = 60;
miniBatchSize = 20;
options = trainingOptions("adam", ...
MaxEpochs=maxEpochs, ...
MiniBatchSize=miniBatchSize, ...
InitialLearnRate=0.01, ...
GradientThreshold=1, ...
Shuffle="never", ...
Metrics="rmse", ...
Plots="training-progress", ...
Verbose=0);
6、训练网络
使用 trainnet 函数训练神经网络
实现代码
net = trainnet(XTrain,TTrain,layers,"mse",options);
视图效果

7、测试网络
1)提取数据
实现代码
filenamePredictors = fullfile(dataFolder,"test_FD001.txt");
filenameResponses = fullfile(dataFolder,"RUL_FD001.txt");
[XTest,TTest] = processTurboFanDataTest(filenamePredictors,filenameResponses);
2)裁剪数据
实现代码
for i = 1:numel(XTest)
XTest{i}(:,idxConstant) = [];
XTest{i} = (XTest{i} - mu) ./ sig;
TTest{i}(TTest{i} > thr) = thr;
end
3)数据预测
实现代码
YTest = minibatchpredict(net,XTest,MiniBatchSize=1,UniformOutput=false);
4)可视化
实现代码
idx = randperm(numel(YTest),4);
figure
for i = 1:numel(idx)
subplot(2,2,i)
plot(TTest{idx(i)},"--")
hold on
plot(YTest{idx(i)},".-")
hold off
ylim([0 thr + 25])
title("Test Observation " + idx(i))
xlabel("Time Step")
ylabel("RUL")
end
legend(["Test Data" "Predicted"],Location="southeast")
视图效果

5)可视化预测误差
实现代码
for i = 1:numel(TTest)
TTestLast(i) = TTest{i}(end);
YTestLast(i) = YTest{i}(end);
end
figure
rmse = sqrt(mean((YTestLast - TTestLast).^2))
histogram(YTestLast - TTestLast)
title("RMSE = " + rmse)
ylabel("Frequency")
xlabel("Error")
视图效果

8、总结
在 MATLAB 中使用 LSTM 模型进行发动机剩余寿命预测可以通过以下步骤:
数据准备:
- 通过 MATLAB 平台导入发动机运行参数
- 首先对原始数据进行预处理步骤
- 对采集到的数据分别执行去噪与标准化处理
- 按照时间序列特征对原始信号进行提取
- 划分时间段窗口以适应 LSTM 网络的时间依赖特性
- 为后续模型训练需求提供规范化的输入格式
创建 LSTM 模型:
- 通过 MATLAB 的 Neural Network Toolbox 建立 LSTM 模型。
- 配置 LSTM 网络的具体参数设置包括层的数量、神经元个数以及学习率等关键超参数。
- 可利用 MATLAB 提供的训练器(trainNetwork)功能对 LSTM 网络进行训练。
划分数据集: * 预处理后的数据将被划分为训练集合、验证集合与测试集合。
- 训练集合将被用来训练LSTM网络;验证集合将被用来优化模型参数;测试集合将被用来检验模型效果。
模型训练与优化: 基于训练数据构建 LSTM 模型,在训练阶段持续监测损失函数的变化并微调关键参数设置。 通过验证集进行评估以防止模型出现过拟合现象,并最终选取最优模型作为最终输出。
模型预测与评估: 通过训练好的LSTM模型对测试集数据进行预测,并获得发动机剩余寿命的预测值; 采用均方根误差(RMSE)作为评价模型预测准确性的指标。
优化与改进:
- 基于预测结果对发动机维护计划进行优化,并延长设备寿命。
- 通过探索不同配置参数和网络架构方案来持续提升 LSTM 模型性能。
基于以上步骤,在 MATLAB 环境中应用 LSTM 模型来进行发动机剩余寿命预测分析,有助于提升设备维护效率和可靠性。
9、源代码
代码
%% 基于长短记忆网络(LSTM)的发动机剩余寿命预测
%使用长短记忆网络(LSTM)依据时间序列数据预测发动机的剩余使用寿命
%% 数据集处理
%创建一个目录来存储涡轮风扇发动机退化仿真数据集
dataFolder = fullfile(tempdir,"turbofan");
if ~exist(dataFolder,"dir")
mkdir(dataFolder);
end
%% 准备训练数据
%使用函数 processTurboFanDataTrain 从 filenamePredictors 中提取数据并返回元胞数组 XTrain 和 TTrain,其中包含训练预测变量和响应序列。
filenamePredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,TTrain] = processTurboFanDataTrain(filenamePredictors);
%删除具有常量值的特征
XTrainConcatenatedTimesteps = cat(1,XTrain{:});
m = min(XTrainConcatenatedTimesteps,[],1);
M = max(XTrainConcatenatedTimesteps,[],1);
idxConstant = M == m;
for i = 1:numel(XTrain)
XTrain{i}(:,idxConstant) = [];
end
%查看序列中其余特征的数量
numFeatures = size(XTrain{1},2)
%归一化训练预测变量
%将训练预测变量归一化为具有零均值和单位方差。
XTrainConcatenatedTimesteps = cat(1,XTrain{:});
mu = mean(XTrainConcatenatedTimesteps,1);
sig = std(XTrainConcatenatedTimesteps,0,1);
for i = 1:numel(XTrain)
XTrain{i} = (XTrain{i} - mu) ./ sig;
end
%裁剪响应
%更多地从发动机快要出现故障时的序列数据中进行学习,以阈值 150 对响应进行裁剪。这会使网络将具有更高 RUL 值的实例视为等同。
thr = 150;
for i = 1:numel(TTrain)
TTrain{i}(TTrain{i} > thr) = thr;
end
%准备要填充的数据
%均匀划分训练数据的小批量大小,并减少小批量中的填充量
%按序列长度对训练数据进行排序
for i=1:numel(XTrain)
sequence = XTrain{i};
sequenceLengths(i) = size(sequence,1);
end
[sequenceLengths,idx] = sort(sequenceLengths,"descend");
XTrain = XTrain(idx);
TTrain = TTrain(idx);
%查看排序的序列长度
figure
bar(sequenceLengths)
xlabel("Sequence")
ylabel("Length")
title("Sorted Data")
%% 定义网络架构
%创建一个 LSTM 网络,该网络包含一个具有 200 个隐藏单元的 LSTM 层,然后是一个大小为 50 的全连接层和一个丢弃概率为 0.5 的丢弃层。
numResponses = size(TTrain{1},2);
numHiddenUnits = 200;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,OutputMode="sequence")
fullyConnectedLayer(50)
dropoutLayer(0.5)
fullyConnectedLayer(numResponses)];
%指定训练选项
%使用求解器 "adam" 以大小为 20 的小批量进行 60 轮训练。
% 指定学习率为 0.01。防止梯度爆炸,将梯度阈值设置为 1。
% 使序列保持按长度排序,将 Shuffle 选项设置为 "never"。
maxEpochs = 60;
miniBatchSize = 20;
options = trainingOptions("adam", ...
MaxEpochs=maxEpochs, ...
MiniBatchSize=miniBatchSize, ...
InitialLearnRate=0.01, ...
GradientThreshold=1, ...
Shuffle="never", ...
Metrics="rmse", ...
Plots="training-progress", ...
Verbose=0);
%% 训练网络
%使用 trainnet 函数训练神经网络
net = trainnet(XTrain,TTrain,layers,"mse",options);
%% 测试网络
%使用函数 processTurboFanDataTest 从 filenamePredictors 和 filenameResponses 中提取数据并返回元胞数组 XTest 和 TTest,其中分别包含测试预测变量和响应序列
filenamePredictors = fullfile(dataFolder,"test_FD001.txt");
filenameResponses = fullfile(dataFolder,"RUL_FD001.txt");
[XTest,TTest] = processTurboFanDataTest(filenamePredictors,filenameResponses);
%使用与训练数据相同的阈值对测试响应进行裁剪
for i = 1:numel(XTest)
XTest{i}(:,idxConstant) = [];
XTest{i} = (XTest{i} - mu) ./ sig;
TTest{i}(TTest{i} > thr) = thr;
end
%使用神经网络进行预测
YTest = minibatchpredict(net,XTest,MiniBatchSize=1,UniformOutput=false);
%可视化一些预测值
idx = randperm(numel(YTest),4);
figure
for i = 1:numel(idx)
subplot(2,2,i)
plot(TTest{idx(i)},"--")
hold on
plot(YTest{idx(i)},".-")
hold off
ylim([0 thr + 25])
title("Test Observation " + idx(i))
xlabel("Time Step")
ylabel("RUL")
end
legend(["Test Data" "Predicted"],Location="southeast")
%直方图中可视化预测误差
for i = 1:numel(TTest)
TTestLast(i) = TTest{i}(end);
YTestLast(i) = YTest{i}(end);
end
figure
rmse = sqrt(mean((YTestLast - TTestLast).^2))
histogram(YTestLast - TTestLast)
title("RMSE = " + rmse)
ylabel("Frequency")
xlabel("Error")
程序文件
<>
