# 使用深度学习进行“序列到序列”回归

### 下载数据

• 第 1 列 - 单元编号

• 第 2 列 - 周期时间

• 第 3-5 列 - 操作设置

• 第 6-26 列 - 传感器测量值 1-21

```dataFolder = fullfile(tempdir,"turbofan"); if ~exist(dataFolder,"dir") mkdir(dataFolder); end```

```filename = matlab.internal.examples.downloadSupportFile("nnet","data/TurbofanEngineDegradationSimulationData.zip"); unzip(filename,dataFolder)```

### 准备训练数据

```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)`
```numFeatures = 17 ```

```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```

```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")```

### 定义网络架构

```numResponses = size(TTrain{1},2); numHiddenUnits = 200; layers = [ ... sequenceInputLayer(numFeatures) lstmLayer(numHiddenUnits,OutputMode="sequence") fullyConnectedLayer(50) dropoutLayer(0.5) fullyConnectedLayer(numResponses)];```

```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);```

### 训练网络

`net = trainnet(XTrain,TTrain,layers,"mse",options);`

### 测试网络

```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);`

LSTM 网络对不完整序列进行预测，一次预测一个时间步。在每个时间步，网络使用此时间步的值进行预测，网络状态仅根据先前的时间步进行计算。网络在各次预测之间更新其状态。`minibatchpredict` 函数返回这些预测值的序列。预测值的最后一个元素对应于不完整序列的预测 RUL。

```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))```
```rmse = single 21.1070 ```
```histogram(YTestLast - TTestLast) title("RMSE = " + rmse) ylabel("Frequency") xlabel("Error")```

### 参考资料

1. Saxena, Abhinav, Kai Goebel, Don Simon, and Neil Eklund."Damage propagation modeling for aircraft engine run-to-failure simulation."In Prognostics and Health Management, 2008.PHM 2008.International Conference on, pp. 1-9.IEEE, 2008.