このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
深層学習を使用した化学的プロセスの故障検出
この例では、シミュレーション データを使用して化学的プロセスの故障を検出可能なニューラル ネットワークを学習させる方法を説明します。このネットワークは、シミュレーション プロセス内の故障を高い精度で検出します。一般的なワークフローを以下に示します。
データの前処理
層アーキテクチャの設計
ネットワークの学習
検証の実行
ネットワークのテスト
データ セットのダウンロード
この例では、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_1
~xmeas_41
) には TEP の変数の測定値が格納されます。列 45 ~ 55 (
xmv_1
~xmv_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 ネットワークの詳細については、長短期記憶ニューラル ネットワーク (Deep Learning Toolbox)を参照してください。
関数
trainNetwork
(Deep Learning Toolbox)を使用してシーケンスを分類するようネットワークを学習させるには、先にデータを前処理しなければなりません。データは 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 = 7200XVal
のサイズ:(合計シミュレーション数) X (合計故障タイプ数) = 100 X 18 = 1800Xtest
のサイズ:(合計シミュレーション数) 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; 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 層は入力シーケンスの重要な側面のみを記憶する傾向があることから、LSTM 層はシーケンスの分類に適しています。
入力層
sequenceInputLayer
を入力信号の数と同じサイズ (52) に指定します。それぞれ 52 個、40 個、25 個のユニットをもつ 3 つの LSTM 隠れ層を指定します。この指定は、[2] で行った実験をヒントにしています。LSTM ネットワークを使用したシーケンスの分類の詳細については、深層学習を使用したシーケンスの分類 (Deep Learning Toolbox)を参照してください。
過適合を防ぐため、LSTM 層の間にドロップアウト層を 3 つ追加します。ドロップアウト層は、指定された確率に基づき、次の層の入力要素をランダムに 0 に設定します。これにより、ネットワークが層内の少数のニューロンの影響を受け過ぎないようにします。
最後に、分類のために、出力クラス数と同じサイズ (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'
の既定値を 'auto'
のままにします。この設定にすると、実行環境がソフトウェアによって自動的に選択されます。既定では、trainNetwork
は GPU が使用可能であれば GPU を使用し、そうでない場合は CPU を使用します。GPU での学習には、Parallel Computing Toolbox™ およびサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。この例は大量のデータを使用するため、GPU を使用すると学習時間が大幅に短縮されます。
名前と値の引数ペア 'Shuffle'
を 'every-epoch'
に設定すると、エポックごとに同一データを破棄するのを避けることができます。
深層学習の学習オプションの詳細については、trainingOptions
(Deep Learning Toolbox)を参照してください。
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);
混同行列を使用すると、分類ネットワークの有効性を評価できます。混同行列は、主対角に数値、それ以外の場所にゼロをもちます。本例の学習済みネットワークは有効であり、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 配列の 1 要素です。各 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
参考
trainNetwork
(Deep Learning Toolbox) | trainingOptions
(Deep Learning Toolbox)
関連するトピック
- 長短期記憶ニューラル ネットワーク (Deep Learning Toolbox)
- 深層学習を使用したシーケンスの分類 (Deep Learning Toolbox)