主要内容

为使用深度学习的序列到序列回归生成通用的C/ c++代码

该示例演示了如何为长短期记忆(LSTM)网络生成不依赖任何第三方深度学习库的纯C/ c++代码。生成一个MEX函数,该函数接受表示发动机中各种传感器的时间序列数据。然后,MEX函数对输入时间序列的每一步进行预测,以周期为单位预测发动机的剩余使用寿命(RUL)。

本示例使用[1]中描述的涡扇发动机退化模拟数据集和预训练的LSTM网络来预测发动机的剩余使用寿命。利用100台发动机的模拟时间序列数据和每个序列末尾的剩余使用寿命对应值进行网络训练。该训练数据中的每个序列都有不同的长度,对应于一个完整的运行到故障(RTF)实例。有关培训网络的更多信息,请参见示例使用深度学习的序列对序列回归

定义入口点函数rulPredict

rulPredict入口点函数接受输入序列,并将其传递给经过训练的序列对序列LSTM网络进行预测。对象加载网络对象rulNetwork.mat文件保存到持久变量中,并在后续的预测调用中重用持久对象。LSTM网络对局部序列进行一次一步的预测。在每个时间步中,网络使用该时间步的值进行预测,而仅使用从以前的时间步计算出的网络状态。网络在每次预测之间更新它的状态。的预测函数返回这些预测的序列。预测的最后一个元素对应于部分序列的预测RUL。

要显示网络体系结构的交互式可视化和有关网络层的信息,请使用analyzeNetwork函数。

类型rulPredict.m
function out = rulPredict(in) %#codegen % Copyright 2020 The MathWorks, Inc. persistent mynet;if isempty(mynet) mynet = code . loaddeeplearningnetwork ('rulNetwork.mat');为了防止函数向数据添加填充,指定小批量大小为1。out = predict(mynet,in,'MiniBatchSize',1);

运行rulPredict有关测试数据

加载TurboFanRULValidateMAT-file。这个mat文件存储变量XValidate它包含传感器读数的样本时间序列数据,用于在MATLAB中测试入口点函数。对测试数据进行预测rulPredict方法。

负载TurboFanRULValidate.matYPred = rulPredict(XValidate);

在一个图中想象一些预测。

idx = randperm(numel(YPred),4);数字i = 1:numel(idx) subplot(2,2,i) plot(YValidate{idx(i)},“——”)举行情节(YPred {idx (i)},“。”)举行Ylim ([0 175]) title(“试验观察”+ idx(i)) xlabel(“时间步”) ylabel (“原则”结束传奇([“测试数据”“预测”],“位置”“东南”

图中包含4个轴对象。标题为Test Observation 82的axis对象1包含2个类型为line的对象。标题为Test Observation 90的axis对象2包含两个类型为line的对象。标题为Test Observation 13的axis对象3包含两个类型为line的对象。标题为Test Observation 89的axis对象4包含两个类型为line的对象。这些对象表示测试数据,预测。

对于给定的部分序列,预测电流RUL是预测序列的最后一个元素。计算预测的均方根误差(RMSE),并将预测误差可视化为直方图。

YValidateLast = 0 (1, numel(YValidate));YPredLast = 0 (1, numel(YValidate));i = 1: numl (YValidate) YValidateLast(i) = YValidate{i}(end);YPredLast(i) = YPred{i}(end);结束figure rmse = sqrt(mean((YPredLast - YValidateLast).^2))
Rmse = 19.0286
直方图(YPredLast - YValidateLast)" rmse = "+ rmse) ylabel(“频率”)包含(“错误”

图中包含一个axes对象。标题为RMSE = 19.0286的axis对象包含一个类型为直方图的对象。

生成MEX函数rulPredict

来生成MEX函数rulPredict入口点函数,创建一个代码生成配置对象cfg用于MEX代码生成。创建一个深度学习配置对象,该对象指定不需要目标库,并将该深度学习配置对象附加到cfg

CFG = code .config(墨西哥人的);cfg。DeepLearningConfig =编码器。DeepLearningConfig (“TargetLibrary”“没有”);

默认情况下,目标语言设置为C。如果希望生成c++代码,请显式地将目标语言设置为c++。

使用coder.typeof函数为入口点函数创建输入类型rulPredict用在arg游戏选项。codegen命令。

的数据XValidate包含100个观测值,其中每个观测值具有双重数据类型,特征维值为17,序列长度可变。为了在一个函数调用中对几个这样的观察结果执行预测,可以将观察结果分组在一个单元格数组中,并传递该单元格数组进行预测。单元格数组必须是列单元格数组,并且每个单元格必须包含一个观察结果。每个观察必须具有相同的特征维度,但序列长度可能根据情况而变化XValidate.指定序列长度为可变长度使我们能够对任意长度的输入序列执行预测。

matrixInput =编码器。类型of(0, [17 Inf],[false true]);%输入类型用于单个观察cellInput = coder。类型of({matrixInput}, [100 1]);%输入类型用于多个观察

运行codegen命令。指定输入类型为cellInput

codegen配置cfgrulPredictarg游戏{cellInput}报告
代码生成成功:要查看报告,请打开('codegen/mex/rulPredict/html/report.mldatx')

在MEX代码生成的默认情况下,生成的代码调用BLAS库进行矩阵操作,并使用OpenMP库(如果编译器支持OpenMP),以便MEX中的任何可并行的for循环都可以在多个线程上运行,从而获得更好的执行性能。金宝app虽然OpenMP默认为独立代码生成而启用,但您必须提供一个自定义BLAS回调,以向MATLAB Coder™指示您希望根据中提到的步骤为矩阵操作生成BLAS调用使用BLAS调用加速独立生成代码中的矩阵运算(MATLAB编码器)

在测试数据上运行生成的MEX函数

通过调用生成的MEX函数对测试数据进行预测rulPredict_mex

YPredMex = rulPredict_mex(XValidate);

你可以在图中想象出和之前一样的预测。

数字i = 1:numel(idx) subplot(2,2,i) plot(YValidate{idx(i)},“——”)举行情节(YPredMex {idx (i)},“。”)举行Ylim ([0 175]) title(“试验观察”+ idx(i)) xlabel(“时间步”) ylabel (“原则”结束传奇([“测试数据”“预测墨西哥人”],“位置”“东南”

图中包含4个轴对象。标题为Test Observation 82的axis对象1包含2个类型为line的对象。标题为Test Observation 90的axis对象2包含两个类型为line的对象。标题为Test Observation 13的axis对象3包含两个类型为line的对象。标题为Test Observation 89的axis对象4包含两个类型为line的对象。这些对象表示测试数据,预测MEX。

计算预测的均方根误差(RMSE),并将预测误差可视化为直方图。

YPredLastMex = 0 (1, numel(YValidate));i = 1:numel(YValidate) YPredLastMex(i) = YPredMex{i}(end);结束figure rmse =√(mean((YPredLastMex - YValidateLast).^2))
Rmse = 19.0286
直方图(YPredLastMex - YValidateLast)" rmse = "+ rmse) ylabel(“频率”)包含(“错误”

图中包含一个axes对象。标题为RMSE = 19.0286的axis对象包含一个类型为直方图的对象。

使用有状态LSTM生成MEX函数

不需要通过整个时间序列一步进行预测,您可以通过使用predictAndUpdateState.当您有到达流的时间步长的值时,这很有用。的predictAndUpdateState函数接受一个输入,产生一个输出预测,并更新网络的内部状态,以便将来的预测考虑到这个初始输入。通常,对完整序列进行预测要比一次一个步骤地进行预测快得多。

入口点功能rulPredictAndUpdate方法接受单时间步输入并处理该输入predictAndUpdateState函数。predictAndUpdateState输出对输入时间步长的预测并更新网络,以便后续输入被视为相同样本的后续时间步。每次传入一个时间步骤之后,结果输出与所有时间步骤作为单个输入传入时相同。

类型rulPredictAndUpdate.m
function out = rulPredictAndUpdate(in) %#codegen % Copyright 2020 The MathWorks, Inc. persistent mynet;if isempty(mynet) mynet = code . loaddeeplearningnetwork ('rulNetwork.mat');end %传递输入到predictAndUpdateState方法[mynet, out] = predictAndUpdateState(mynet, in);

在这个新的入口点函数上运行codegen。由于每次调用都采用单一的时间步,因此我们指定matrixInput用固定的序列尺寸1代替可变的序列长度。

matrixInput = code .typeof(double(0),[17 1]);codegen配置cfgrulPredictAndUpdatearg游戏{matrixInput}报告
代码生成成功:要查看报告,请打开('codegen/mex/rulPredictAndUpdate/html/report.mldatx')

对测试数据进行预测rulPredictAndUpdate函数在MATLAB中d的生成的MEX函数rulPredictAndUpdate_mex

YPredStatefulMex = cell(numel(idx), 1);iSample = 1:numel(idx) sample = XValidate{idx(iSample)};numTimeStepsTest = size(sample, 2);iStep = 1:numTimeStepsTest YPredStatefulMex{iSample}(1, iStep) = rulPredictAndUpdate_mex(sample(:, iStep));结束结束

您可以再次在图中看到有状态MEX的预测。

数字i = 1:numel(idx) subplot(2,2,i) plot(YValidate{idx(i)},“——”)举行情节(YPredStatefulMex {},“。”)举行Ylim ([0 175]) title(“试验观察”+ idx(i)) xlabel(“时间步”) ylabel (“原则”结束传奇([“测试数据”“预测MEX有状态LSTM”],“位置”“东南”

图中包含4个轴对象。标题为Test Observation 82的axis对象1包含2个类型为line的对象。标题为Test Observation 90的axis对象2包含两个类型为line的对象。标题为Test Observation 13的axis对象3包含两个类型为line的对象。标题为Test Observation 89的axis对象4包含两个类型为line的对象。这些对象表示测试数据、预测MEX有状态LSTM。

最后,您还可以将两个不同的MEX函数的结果与MATLAB预测一起在任意特定样本的图中可视化。

图()sampleIdx = idx(1);情节(YValidate {sampleIdx},“——”)举行情节(YPred {sampleIdx},“啊——”)情节(YPredMex {sampleIdx},' ^ - ')情节(YPredStatefulMex {1},“x -”)举行Ylim ([0 175]) title(“试验观察”+ idx(i)) xlabel(“时间步”) ylabel (“原则”)传说([“测试数据”“MATLAB预测”“预测墨西哥人”用有状态LSTM预测MEX],“位置”“东南”

图中包含一个axes对象。标题为Test Observation 89的axis对象包含4个类型为line的对象。这些对象表示测试数据,在MATLAB中预测,预测MEX,预测MEX与有状态LSTM。

参考文献

  1. 萨克森纳,阿比纳夫,凯·戈贝尔,唐·西蒙,尼尔·埃克伦德。用于飞机发动机运行到故障模拟的损伤传播模型。在预测与健康管理,2008年。2008年榜单。国际气候变化会议,第1-9页。IEEE 2008。

另请参阅

(MATLAB编码器)|(MATLAB编码器)|(MATLAB编码器)

相关的话题