Main Content

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

深層学習を使用した化学的プロセスの故障検出

この例では、化学プロセスの故障を検出できるニューラル ネットワークをシミュレーション データで学習させる方法を説明します。このネットワークは、シミュレートされたプロセスの故障を高い精度で検出します。標準的なワークフローは次のとおりです。

  1. データの前処理

  2. 層アーキテクチャの設計

  3. ネットワークの学習

  4. 検証の実行

  5. ネットワークのテスト

データセットのダウンロード

この例では、Tennessee Eastman Process (TEP) シミュレーション データ [1] から MathWorks® によって変換された MATLAB 形式のファイルを使用します。これらのファイルは、MathWorks のサポート ファイルのサイトで入手できます。免責事項を参照してください。

データセットは、故障なし学習、故障なしテスト、故障あり学習、故障ありテストの 4 つのコンポーネント で構成されます。各ファイルを別々にダウンロードします。

url = 'https://www.mathworks.com/supportfiles/predmaint/chemical-process-fault-detection-data/faultytesting.mat';
websave('faultytesting.mat',url);
url = 'https://www.mathworks.com/supportfiles/predmaint/chemical-process-fault-detection-data/faultytraining.mat';
websave('faultytraining.mat',url);
url = 'https://www.mathworks.com/supportfiles/predmaint/chemical-process-fault-detection-data/faultfreetesting.mat';
websave('faultfreetesting.mat',url);
url = 'https://www.mathworks.com/supportfiles/predmaint/chemical-process-fault-detection-data/faultfreetraining.mat';
websave('faultfreetraining.mat',url);

ダウンロードしたファイルを MATLAB® ワークスペースに読み込みます。

load('faultfreetesting.mat');
load('faultfreetraining.mat');
load('faultytesting.mat');
load('faultytraining.mat');

各コンポーネントには、2 つのパラメーターのすべての順列について実行されたシミュレーションからのデータが含まれています。

  • 故障番号 — 故障ありのデータセットの場合、シミュレートされた各故障を表す 1 ~ 20 の整数値。故障なしのデータセットの場合、値は 0。

  • シミュレーション実行回数 — すべてのデータセットについて、1 ~ 500 の整数値。各値は、シミュレーションで使用する乱数発生器の一意の状態を表します。

各シミュレーションの長さはデータセットに依存します。すべてのシミュレーションが 3 分ごとにサンプリングされました。

  • 学習データセットには、25 時間のシミュレーションから得られた 500 個の時間サンプルが含まれています。

  • テスト データ セットには、48 時間のシミュレーションで得られた 960 回分のサンプルが含まれています。

各データ フレームの列には次の変数が格納されています。

  • 列 1 (faultNumber) は故障タイプを示し、0 ~ 20 の値を取ります。故障番号 0 は故障がないことを意味し、故障番号 1 ~ 20 は TEP 内の異なる故障タイプを表します。

  • 列 2 (simulationRun) は、完全なデータを取得するために TEP シミュレーションを実行した回数を示します。学習データセットとテスト データセットでは、すべての故障番号について実行数が 1 ~ 500 の範囲で変動します。各 simulationRun の各値は、そのシミュレーションの異なる乱数発生器の状態を表します。

  • 列 3 (sample) は、シミュレーションごとに TEP 変数を記録した回数を表します。この回数は、学習データセットでは 1 ~ 500、テスト データセットでは 1 ~ 960 の範囲で変動します。TEP 変数 (列 4 ~ 55) は、3 分ごとに、学習データセットの場合は 25 時間、テスト データセットの場合は 48 時間にわたってサンプリングされています。

  • 列 4 ~ 44 (xmeas_1xmeas_41) には、測定された TEP 変数が格納されます。

  • 列 45 ~ 55 (xmv_1xmv_11) には、TEP の操作変数が格納されます。

2 つのファイルのサブセクションを調べます。

head(faultfreetraining,4)    
ans=4×55 table
    faultNumber    simulationRun    sample    xmeas_1    xmeas_2    xmeas_3    xmeas_4    xmeas_5    xmeas_6    xmeas_7    xmeas_8    xmeas_9    xmeas_10    xmeas_11    xmeas_12    xmeas_13    xmeas_14    xmeas_15    xmeas_16    xmeas_17    xmeas_18    xmeas_19    xmeas_20    xmeas_21    xmeas_22    xmeas_23    xmeas_24    xmeas_25    xmeas_26    xmeas_27    xmeas_28    xmeas_29    xmeas_30    xmeas_31    xmeas_32    xmeas_33    xmeas_34    xmeas_35    xmeas_36    xmeas_37    xmeas_38    xmeas_39    xmeas_40    xmeas_41    xmv_1     xmv_2     xmv_3     xmv_4     xmv_5     xmv_6     xmv_7     xmv_8     xmv_9     xmv_10    xmv_11
    ___________    _____________    ______    _______    _______    _______    _______    _______    _______    _______    _______    _______    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ______    ______    ______    ______    ______    ______    ______    ______    ______    ______    ______

         0               1            1       0.25038      3674       4529      9.232     26.889     42.402     2704.3     74.863     120.41     0.33818      80.044      51.435      2632.9      25.029      50.528      3101.1      22.819      65.732      229.61      341.22       94.64      77.047      32.188      8.8933      26.383       6.882      18.776      1.6567      32.958      13.823      23.978      1.2565      18.579      2.2633      4.8436      2.2986     0.017866     0.8357     0.098577     53.724      43.828     62.881    53.744    24.657    62.544    22.137    39.935    42.323    47.757     47.51    41.258    18.447
         0               1            2       0.25109    3659.4     4556.6     9.4264     26.721     42.576       2705         75     120.41      0.3362      80.078      50.154      2633.8      24.419      48.772        3102      23.333      65.716      230.54       341.3      94.595      77.434      32.188      8.8933      26.383       6.882      18.776      1.6567      32.958      13.823      23.978      1.2565      18.579      2.2633      4.8436      2.2986     0.017866     0.8357     0.098577     53.724      43.828     63.132    53.414    24.588    59.259    22.084    40.176    38.554    43.692    47.427    41.359    17.194
         0               1            3       0.25038    3660.3     4477.8     9.4426     26.875      42.07     2706.2     74.771     120.42     0.33563       80.22      50.302      2635.5      25.244      50.071      3103.5      21.924      65.732      230.08      341.38      94.605      77.466      31.767      8.7694      26.095      6.8259      18.961      1.6292      32.985      13.742      23.897      1.3001      18.765      2.2602      4.8543        2.39     0.017866     0.8357     0.098577     53.724      43.828     63.117    54.357    24.666    61.275     22.38    40.244     38.99    46.699    47.468    41.199     20.53
         0               1            4       0.24977    3661.3     4512.1     9.4776     26.758     42.063     2707.2     75.224     120.39     0.33553      80.305       49.99      2635.6      23.268      50.435      3102.8      22.948      65.781      227.91      341.71      94.473      77.443      31.767      8.7694      26.095      6.8259      18.961      1.6292      32.985      13.742      23.897      1.3001      18.765      2.2602      4.8543        2.39     0.017866     0.8357     0.098577     53.724      43.828       63.1    53.946    24.725    59.856    22.277    40.257    38.072    47.541    47.658    41.643    18.089

head(faultytraining,4)       
ans=4×55 table
    faultNumber    simulationRun    sample    xmeas_1    xmeas_2    xmeas_3    xmeas_4    xmeas_5    xmeas_6    xmeas_7    xmeas_8    xmeas_9    xmeas_10    xmeas_11    xmeas_12    xmeas_13    xmeas_14    xmeas_15    xmeas_16    xmeas_17    xmeas_18    xmeas_19    xmeas_20    xmeas_21    xmeas_22    xmeas_23    xmeas_24    xmeas_25    xmeas_26    xmeas_27    xmeas_28    xmeas_29    xmeas_30    xmeas_31    xmeas_32    xmeas_33    xmeas_34    xmeas_35    xmeas_36    xmeas_37    xmeas_38    xmeas_39    xmeas_40    xmeas_41    xmv_1     xmv_2     xmv_3     xmv_4     xmv_5     xmv_6     xmv_7     xmv_8     xmv_9     xmv_10    xmv_11
    ___________    _____________    ______    _______    _______    _______    _______    _______    _______    _______    _______    _______    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ________    ______    ______    ______    ______    ______    ______    ______    ______    ______    ______    ______

         1               1            1       0.25038      3674       4529      9.232     26.889     42.402     2704.3     74.863     120.41     0.33818      80.044      51.435      2632.9      25.029      50.528      3101.1      22.819      65.732      229.61      341.22       94.64      77.047      32.188      8.8933      26.383       6.882      18.776      1.6567      32.958      13.823      23.978      1.2565      18.579      2.2633      4.8436      2.2986     0.017866     0.8357     0.098577     53.724      43.828     62.881    53.744    24.657    62.544    22.137    39.935    42.323    47.757     47.51    41.258    18.447
         1               1            2       0.25109    3659.4     4556.6     9.4264     26.721     42.576       2705         75     120.41      0.3362      80.078      50.154      2633.8      24.419      48.772        3102      23.333      65.716      230.54       341.3      94.595      77.434      32.188      8.8933      26.383       6.882      18.776      1.6567      32.958      13.823      23.978      1.2565      18.579      2.2633      4.8436      2.2986     0.017866     0.8357     0.098577     53.724      43.828     63.132    53.414    24.588    59.259    22.084    40.176    38.554    43.692    47.427    41.359    17.194
         1               1            3       0.25038    3660.3     4477.8     9.4426     26.875      42.07     2706.2     74.771     120.42     0.33563       80.22      50.302      2635.5      25.244      50.071      3103.5      21.924      65.732      230.08      341.38      94.605      77.466      31.767      8.7694      26.095      6.8259      18.961      1.6292      32.985      13.742      23.897      1.3001      18.765      2.2602      4.8543        2.39     0.017866     0.8357     0.098577     53.724      43.828     63.117    54.357    24.666    61.275     22.38    40.244     38.99    46.699    47.468    41.199     20.53
         1               1            4       0.24977    3661.3     4512.1     9.4776     26.758     42.063     2707.2     75.224     120.39     0.33553      80.305       49.99      2635.6      23.268      50.435      3102.8      22.948      65.781      227.91      341.71      94.473      77.443      31.767      8.7694      26.095      6.8259      18.961      1.6292      32.985      13.742      23.897      1.3001      18.765      2.2602      4.8543        2.39     0.017866     0.8357     0.098577     53.724      43.828       63.1    53.946    24.725    59.856    22.277    40.257    38.072    47.541    47.658    41.643    18.089

データのクリーンアップ

学習データセットとテスト データセットの両方で、故障番号が 3、9 および 15 のデータ エントリを削除します。これらの故障番号は認識が不可能で、関連するシミュレーション結果は誤りです。

faultytesting(faultytesting.faultNumber == 3,:) = [];
faultytesting(faultytesting.faultNumber == 9,:) = [];
faultytesting(faultytesting.faultNumber == 15,:) = [];


faultytraining(faultytraining.faultNumber == 3,:) = [];
faultytraining(faultytraining.faultNumber == 9,:) = [];
faultytraining(faultytraining.faultNumber == 15,:) = [];

データの分割

検証用に学習データの 20% を予約することによって、学習データを学習データと検証データに分割します。検証データセットを使用すると、モデルのハイパーパラメーターを調整しながら、学習データセットへのモデルの適合を評価できます。データの分割は、ネットワークの過適合や適合不足を防ぐためによく使用されます。

故障ありと故障なしの両方の学習データセットで、行の総数を取得します。

H1 = height(faultfreetraining); 
H2 = height(faultytraining);    

シミュレーション実行数は、特定の故障タイプで TEP プロセスを繰り返した回数です。学習データセットとテスト データセットの両方から、最大のシミュレーション実行数を取得します。

msTrain = max(faultfreetraining.simulationRun); 
msTest = max(faultytesting.simulationRun);      

検証データについて最大のシミュレーション実行数を計算します。

rTrain = 0.80; 
msVal = ceil(msTrain*(1 - rTrain));    
msTrain = msTrain*rTrain;   

サンプルまたはタイム ステップの最大数 (つまり、TEP シミュレーション中にデータが記録された最大の回数) を取得します。

sampleTrain = max(faultfreetraining.sample);
sampleTest = max(faultfreetesting.sample);

故障なしと故障ありの学習データセットで分割点 (行番号) を取得して、学習データセットから検証データセットを作成します。

rowLim1 = ceil(rTrain*H1);
rowLim2 = ceil(rTrain*H2);

trainingData = [faultfreetraining{1:rowLim1,:}; faultytraining{1:rowLim2,:}];
validationData = [faultfreetraining{rowLim1 + 1:end,:}; faultytraining{rowLim2 + 1:end,:}];
testingData = [faultfreetesting{:,:}; faultytesting{:,:}];

ネットワークの設計と前処理

最終データセット (学習データ、検証データ、およびテスト データで構成) には、500 個の等間隔のタイム ステップをもつ 52 個の信号が格納されています。そのため、信号つまりシーケンスを正しい故障番号に分類する必要があるため、これはシーケンス分類の問題となります。

  • 長短期記憶 (LSTM) ネットワークは、シーケンス データの分類に適しています。

  • LSTM ネットワークは、新しい信号を分類するために過去の信号の一意性を記憶する傾向があるため、時系列データに向いています。

  • LSTM ネットワークでは、シーケンス データをネットワークに入力し、シーケンス データの個々のタイム ステップに基づいて予測を行うことができます。LSTM ネットワークの詳細については、長短期記憶ネットワークを参照してください。

  • 関数 trainNetwork を使用してシーケンスを分類するようにネットワークを学習させるには、最初にデータを前処理しなければなりません。データは cell 配列でなければなりません。ここで cell 配列の各要素は 1 回のシミュレーションに含まれる 52 個の信号のセットを表す行列です。cell 配列の各行列は、TEP の特定のシミュレーションの信号セットであり、故障ありまたは故障なしのいずれかにできます。信号の各セットは 0 ~ 20 の範囲の特定の故障クラスを指しています。

データセット セクションで前述したように、データには 52 個の変数が格納されており、その値はシミュレーションにおいて特定の時間にわたって記録されます。変数 sample は、この 52 個の変数が 1 回のシミュレーション実行で記録される回数を表します。変数 sample の最大値は、学習データセットでは 500、テスト データセットでは 960 です。したがって、シミュレーションごとに、長さが 500 または 960 の 52 個の信号のセットが存在します。信号の各セットは、TEP の特定のシミュレーション実行に属し、範囲 0 ~ 20 の特定の故障タイプを指します。

学習データセットとテスト データセットは両方とも各故障タイプについて 500 個のシミュレーションを含みます。学習データから 20% が検証用に保持されるため、学習データセットには各故障タイプにつき 400 個のシミュレーション、検証データには各故障タイプにつき 100 個のシミュレーションが残ります。補助関数 helperPreprocess を使用して信号のセットを作成します。ここで各セットは、1 回の TEP シミュレーションを表す cell 配列の単一要素に含まれる double 行列です。そのため、学習データセット、検証データセット、およびテスト データセットの最終的なサイズは次のようになります。

  • Xtrain のサイズ: (シミュレーションの総数) X (故障タイプの総数) = 400 X 18 = 7200

  • XVal のサイズ: (シミュレーションの総数) X (故障の種類の総数) = 100 X 18 = 1800

  • Xtest のサイズ: (シミュレーションの総数) X (故障の種類の総数) = 500 X 18 = 9000

データセットにおいて、最初の 500 回のシミュレーションは故障タイプが 0 (故障なし) であり、それ以降の故障ありのシミュレーションの順序はわかっています。この情報により、学習データセット、検証データセット、およびテスト データセットに対する真の応答の作成が可能になります。

Xtrain = helperPreprocess(trainingData,sampleTrain);
Ytrain = categorical([zeros(msTrain,1);repmat([1,2,4:8,10:14,16:20],1,msTrain)']);
 
XVal = helperPreprocess(validationData,sampleTrain);
YVal = categorical([zeros(msVal,1);repmat([1,2,4:8,10:14,16:20],1,msVal)']);
 
Xtest = helperPreprocess(testingData,sampleTest);
Ytest = categorical([zeros(msTest,1);repmat([1,2,4:8,10:14,16:20],1,msTest)']);

データセットの正規化

正規化は、値の範囲内の差異を歪めることなく、データセット内の数値を共通の尺度にスケーリングする手法です。この手法によって、大きな値をもつ変数が学習中に他の変数の優位にならないようにします。また、学習に必要となる重要な情報を失うことなく、大きな範囲の数値を小さな範囲 (通常 –1 ~ 1) に変換します。

学習データセットに含まれるすべてのシミュレーションからのデータを使用して、52 個の信号の平均と標準偏差を計算します。

tMean = mean(trainingData(:,4:end))';
tSigma = std(trainingData(:,4:end))';

補助関数 helperNormalize を使用して、学習データの平均と標準偏差に基づき、3 つのデータセット内の各 cell に正規化を適用します。

Xtrain = helperNormalize(Xtrain, tMean, tSigma);
XVal = helperNormalize(XVal, tMean, tSigma);
Xtest = helperNormalize(Xtest, tMean, tSigma);

データの可視化

Xtrain データセットには、400 回の故障なしシミュレーション、その後に 6800 回の故障ありシミュレーションが含まれます。故障なしのデータと故障ありのデータを可視化します。最初に、故障なしのデータのプロットを作成します。この例の目的上、Xtrain データセット内の 10 個の信号のみをプロットしてラベルを付け、読みやすい Figure を作成します。

figure;
splot = 10;    
plot(Xtrain{1}(1:10,:)');   
xlabel("Time Step");
title("Training Observation for Non-Faulty Data");
legend("Signal " + string(1:splot),'Location','northeastoutside');

次に、400 以降の任意の cell 配列要素をプロットして、故障なしのプロットと故障ありのプロットを比較します。

figure;
plot(Xtrain{1000}(1:10,:)');   
xlabel("Time Step");
title("Training Observation for Faulty Data");
legend("Signal " + string(1:splot),'Location','northeastoutside');

層アーキテクチャと学習オプション

LSTM 層は、入力シーケンスの重要な部分のみを記憶する傾向があるため、シーケンス分類に適しています。

  • 入力層 sequenceInputLayer を入力信号の数 (52) と同じサイズに指定します。

  • 3 つの LSTM 隠れ層を指定し、それぞれ 52 個、40 個、25 個のユニットをもたせます。この指定は、[2] で行った実験からヒントを得ています。LSTM ネットワークを使用したシーケンス分類の詳細については、深層学習を使用したシーケンスの分類を参照してください。

  • 過適合を防ぐため、LSTM 層の間に 3 つのドロップアウト層を追加します。ドロップアウト層は、ネットワークが層内の少数のニューロンのセットから影響を受けないよう、指定の確率でランダムに次の層の入力要素をゼロに設定します。

  • 最後に、分類のために、出力クラスの数 (18) と同じサイズの全結合層を含めます。全結合層の後に、複数クラス問題の各クラスに小数の確率値 (予測可能性) を割り当てるソフトマックス層と、ソフトマックス層からの出力を基に最終的な故障タイプを出力する分類層を含めます。

numSignals = 52;
numHiddenUnits2 = 52;
numHiddenUnits3 = 40;
numHiddenUnits4 = 25;
numClasses = 18;
     
layers = [ ...
    sequenceInputLayer(numSignals)
    lstmLayer(numHiddenUnits2,'OutputMode','sequence')
    dropoutLayer(0.2)
    lstmLayer(numHiddenUnits3,'OutputMode','sequence')
    dropoutLayer(0.2)
    lstmLayer(numHiddenUnits4,'OutputMode','last')
    dropoutLayer(0.2)
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];

trainNetwork を使用する学習オプションを設定します。

名前と値のペア 'ExecutionEnvironment' as の既定値を 'auto' のままにします。この設定では、ソフトウェアが実行環境を自動的に選択します。GPU が利用可能な場合 (Parallel Computing Toolbox™、および Compute Capability 3.0 以上の CUDA® 対応 GPU が必要)、ソフトウェアはその GPU を使用します。そうでない場合、ソフトウェアは CPU を使用します。この例は大量のデータを使用するため、GPU を使用すると学習時間が大幅に短縮されます。

名前と値の引数のペア 'Shuffle''every-epoch' に設定すると、すべてのエポックで同じデータが破棄されるのを回避できます。

深層学習の学習オプションの詳細については、trainingOptions を参照してください。

maxEpochs = 30;
miniBatchSize = 50;  
 
options = trainingOptions('adam', ...
    'ExecutionEnvironment','auto', ...
    'GradientThreshold',1, ...
    'MaxEpochs',maxEpochs, ...
    'MiniBatchSize', miniBatchSize,...
    'Shuffle','every-epoch', ...
    'Verbose',0, ...
    'Plots','training-progress',...
    'ValidationData',{XVal,YVal});

ネットワークの学習

trainNetwork を使用して LSTM ネットワークに学習させます。

net = trainNetwork(Xtrain,Ytrain,layers,options);

学習進行状況の図は、ネットワークの精度のプロットを示しています。図の右側で、学習時間と設定に関する情報を確認します。

ネットワークのテスト

テスト セットで学習済みネットワークを実行し、信号内の故障タイプを予測します。

Ypred = classify(net,Xtest,...
    'MiniBatchSize', miniBatchSize,...
    'ExecutionEnvironment','auto');

精度を計算します。精度とは、classify による分類に一致するテスト データ内の真のラベルの数を、テスト データ内のイメージの数で除算したものです。

acc = sum(Ypred == Ytest)./numel(Ypred)
acc = 0.9992

高い精度は、ニューラル ネットワークが未知の信号の故障タイプを最小限の誤差で正しく特定できたことを示します。そのため、精度が高いほど、ネットワークは優れたものとなります。

テスト信号の真のクラス ラベルを使用して混同行列をプロットし、ネットワークが各故障がどの程度正しく特定しているかを判定します。

confusionchart(Ytest,Ypred);

混同行列を使用すると、分類ネットワークの有効性を評価できます。混同行列は、主対角に数値、それ以外の場所に 0 をもちます。この例の学習済みネットワークは有効であり、信号の 99% 以上を正しく分類します。

参考文献

[1] Rieth, C. A., B. D. Amsel, R. Tran., and B. Maia. "Additional Tennessee Eastman Process Simulation Data for Anomaly Detection Evaluation." Harvard Dataverse, Version 1, 2017. https://doi.org/10.7910/DVN/6C3JR1.

[2] Heo, S., and J. H. Lee. "Fault Detection and Classification Using Artificial Neural Networks." Department of Chemical and Biomolecular Engineering, Korea Advanced Institute of Science and Technology.

補助関数

helperPreprocess

補助関数 helperPreprocess は、最大サンプル番号を使用してデータを前処理します。サンプル番号は信号長を示し、これはデータセット全体で一貫しています。データセットに対して信号長のフィルターを含む for ループを実行し、52 個の信号のセットを生成します。各セットは cell 配列の要素です。各 cell 配列は 1 回のシミュレーションを表します。

function processed = helperPreprocess(mydata,limit)
    H = size(mydata);
    processed = {};
    for ind = 1:limit:H
        x = mydata(ind:(ind+(limit-1)),4:end);
        processed = [processed; x'];
    end
end

helperNormalize

補助関数 helperNormalize は、データ、平均、および標準偏差を使用してデータを正規化します。

function data = helperNormalize(data,m,s)
    for ind = 1:size(data)
        data{ind} = (data{ind} - m)./s;
    end
end

参考

| | |

関連するトピック