主要内容

使用深度学习生成序列到序列回归的通用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。出=预测(mynet, MiniBatchSize, 1);

运行rulPredict在测试数据

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

负载TurboFanRULValidate.matYPred = rulPredict (XValidate);

在一个情节中设想一些预测。

idx = randperm(元素个数(YPred), 4);数字YValidate{idx(i)}:“——”)举行情节(YPred {idx (i)},“。”)举行ylim(175[0])标题(“测试观察”+ idx (i))包含(“时间步”) ylabel (“原则”结束传奇([“测试数据”“预测”],“位置”“东南”

图中包含4个轴对象。标题为“测试观察82”的轴对象1包含2个类型为line的对象。标题为“测试观察90”的轴对象2包含2个类型为line的对象。标题为测试观察13的轴对象3包含2个类型为line的对象。标题为测试观察89的轴对象4包含2个类型为line的对象。这些对象表示预测的测试数据。

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

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

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

生成MEX函数rulPredict

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

cfg = coder.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 =编码器。类型of({matrixInput}, [100 1]);%输入类型的多个观察

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

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

默认情况下,对于MEX代码生成,生成的代码调用BLAS库进行矩阵操作,并使用OpenMP库(如果编译器支持OpenMP),以便MEX中的任何可并行化的for循环可以在多个线程上运行,从而获得更好的执行性能。万博1manbetx虽然OpenMP在默认情况下是为独立代码生成而启用的,但您必须提供一个自定义BLAS回调,以向MATLAB Coder™表明您想按照中提到的步骤生成矩阵操作的BLAS调用通过使用BLAS调用加速生成的独立代码中的矩阵运算

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

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

YPredMex = rulPredict_mex (XValidate);

你可以在一个图中想象同样的预测。

数字YValidate{idx(i)}:“——”)举行情节(YPredMex {idx (i)},“。”)举行ylim(175[0])标题(“测试观察”+ idx (i))包含(“时间步”) ylabel (“原则”结束传奇([“测试数据”“预测墨西哥人”],“位置”“东南”

图中包含4个轴对象。标题为“测试观察82”的轴对象1包含2个类型为line的对象。标题为“测试观察90”的轴对象2包含2个类型为line的对象。标题为测试观察13的轴对象3包含2个类型为line的对象。标题为测试观察89的轴对象4包含2个类型为line的对象。这些对象代表测试数据,预测的MEX。

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

YPredLastMex = zeros(1, numel(YValidate)); / /输入字符串i = 1:numel(YValidate) YPredLastMex(i) = YPredMex{i}(end);结束图rmse = sqrt(mean((YPredLastMex - YValidateLast).^2)))
rmse = 19.0286
直方图(YPredLastMex - YValidateLast)" RMSE = "+ rmse) ylabel (“频率”)包含(“错误”

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

用有状态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 % pass in input to predictAndUpdateState method [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函数的MATLABd的墨西哥人函数生成rulPredictAndUpdate_mex

YPredStatefulMex = cell(numel(idx), 1); / /显示当前状态iSample = 1:numel(idx) sample = XValidate{idx(iSample)};numTimeStepsTest = size(sample, 2);isstep = 1:numTimeStepsTest YPredStatefulMex{iSample}(1, iStep) = rulPredictAndUpdate_mex(sample(:, iStep));结束结束

同样,您可以像以前一样在图中可视化有状态MEX的预测。

数字YValidate{idx(i)}:“——”)举行情节(YPredStatefulMex {},“。”)举行ylim(175[0])标题(“测试观察”+ idx (i))包含(“时间步”) ylabel (“原则”结束传奇([“测试数据”“Predicted MEX Stateful LSTM”],“位置”“东南”

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

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

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

图中包含一个轴对象。标题为Test Observation 89的轴对象包含4个类型为line的对象。这些对象分别代表测试数据、MATLAB预测数据、预测MEX数据、有状态LSTM预测MEX数据。

参考文献

  1. 萨克斯纳,阿比纳夫,凯·戈贝尔,唐·西蒙,尼尔·埃克隆德。"飞机发动机从运行到故障的损伤传播模型"在预测与健康管理,2008年。2008年榜单。国际会议上1 - 9页。IEEE 2008。

另请参阅

||

相关的话题