Main Content

Intel MKL-DNN を使用した LSTM ネットワークのコード生成

この例では、Intel Math Kernel Library for Deep Neural Networks (MKL-DNN) を使用する事前学習済みの長短期記憶 (LSTM) ネットワークのコードを生成する方法を説明します。この例では、入力時系列の各ステップの予測を行う MEX 関数を生成します。この例では、2 つの方法を説明します。1 番目の方法は、標準の LSTM ネットワークを使用します。2 番目の方法は、同じ LSTM ネットワークのステートフルな動作を利用します。この例では、出荷時のイベントを説明するテキストを使用して次の 4 つのカテゴリのいずれかに分類します。Electronic Failure、Leak、Mechanical Failure、Software Failure。この例では事前学習済みの LSTM ネットワークを使用します。ネットワークの学習の詳細については、Classify Text Data Using Deep Learning (Text Analytics Toolbox)を参照してください。

サードパーティの必要条件

  • Intel Math Kernel Library for Deep Neural Networks (MKL-DNN)

  • MKL-DNN ライブラリをサポートするプロセッサの一覧については、MKLDNN CPU サポートを参照してください

  • サポートされているコンパイラおよびライブラリのバージョンの詳細については、MATLAB Coder を使用した深層学習の前提条件 (MATLAB Coder)を参照してください

この例は、Mac®、Linux®、および Windows® の各プラットフォームでサポートされていますが、MATLAB Online ではサポートされていません。

入力の準備

wordEncoding MAT ファイルを読み込みます。この MAT ファイルには、数値インデックスとして符号化された単語が保存されます。この符号化は、ネットワークの学習中に実行されました。詳細については、Classify Text Data Using Deep Learning (Text Analytics Toolbox)を参照してください。

load("wordEncoding.mat");

新しいレポートを含む string 配列を作成し、イベント タイプを分類します。

reportsNew = [ ...
    "Coolant is pooling underneath sorter."
    "Sorter blows fuses at start up."
    "There are some very loud rattling sounds coming from the assembler."
    "At times mechanical arrangement software freezes."
    "Mixer output is stuck."];

関数 preprocessText を使用して、入力文字列をトークン化します。

documentsNew = preprocessText(reportsNew);

関数doc2sequence (Text Analytics Toolbox)を使用して、ドキュメントをシーケンスに変換します。

XNew = doc2sequence(enc,documentsNew);
labels = categorical({'Electronic Failure', 'Leak', 'Mechanical Failure', 'Software Failure'});

エントリポイント関数 lstm_predict

sequence-to-sequence LSTM ネットワークでは、データ シーケンスの個々のタイム ステップで異なる予測を行うことができます。エントリポイント関数 lstm_predict.m は、入力シーケンスを受け取り、予測用の学習済み LSTM ネットワークに渡します。具体的には、関数はClassify Text Data Using Deep Learning (Text Analytics Toolbox)の例で学習させる LSTM ネットワークを使用します。関数は、textClassifierNetwork.mat ファイルからネットワーク オブジェクトを永続変数に読み込んでから、予測を実行します。それ以降の呼び出しでは、関数はこの永続オブジェクトを再利用します。

type('lstm_predict.m')
function out = lstm_predict(in)
%#codegen

%   Copyright 2020 The MathWorks, Inc.

    persistent mynet;

    if isempty(mynet)
        mynet = coder.loadDeepLearningNetwork('textClassifierNetwork.mat');
    end

    out = predict(mynet, in);
end

ネットワーク アーキテクチャの対話的な可視化とネットワーク層についての詳細情報を表示するには、関数analyzeNetworkを使用します。

MEX 生成

コードを生成するには、MEX ターゲットのコード構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数 coder.DeepLearningConfig を使用して MKL-DNN 深層学習の構成オブジェクトを作成します。これをコード構成オブジェクトの DeepLearningConfig プロパティに割り当てます。

cfg = coder.config('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('mkldnn');

関数coder.typeof (MATLAB Coder)を使用してエントリポイント関数への入力引数の型とサイズを指定します。この例では、入力は、特徴次元値 1 と可変のシーケンス長をもつ double のデータ型です。

matrixInput = coder.typeof(double(0),[1 Inf],[false true]);

codegen (MATLAB Coder)コマンドを実行して、MEX 関数を生成します。

codegen -config cfg lstm_predict -args {matrixInput} -report
Code generation successful: View report

生成された MEX の実行

最初の観測値について lstm_predict_mex を呼び出します。

YPred1 = lstm_predict_mex(XNew{1});

YPred1 には、4 つのクラスの確率が含まれています。最大確率のインデックスを計算して、予測されたクラスを見つけます。

[~, maxIndex] = max(YPred1);

最大確率のインデックスを対応するラベルに関連付けます。分類を表示します。結果から、ネットワークが最初のイベントを Leak と予測したことがわかります。

predictedLabels1 = labels(maxIndex);
disp(predictedLabels1)
     Leak 

複数の観測値を受け入れる MEX の生成

多数の観測値について一度に予測を行う場合は、観測値をまとめて cell 配列にグループ化し、予測のためその cell 配列を渡すことができます。この cell 配列は列セル配列でなければならず、各 cell には 1 つの観測値が含まれていなければなりません。入力のシーケンス長は異なる場合があります。この例では、XNew には 5 つの観測値が含まれています。XNew を入力として受け入れる MEX 関数を生成するには、入力の型を 5 行 1 列の cell 配列になるよう指定します。各セルが matrixInput と同じ型になるよう指定します。

matrixInput = coder.typeof(double(0),[1 Inf],[false true]);
cellInput = coder.typeof({matrixInput}, [5 1]);
codegen -config cfg lstm_predict -args {cellInput} -report
Code generation successful: View report

XNew を入力とし、生成された MEX 関数を実行します。

YPred2 = lstm_predict_mex(XNew);

YPred2 は 5 行 4 列の cell 配列です。5 つの各入力について最大確率のインデックスを見つけ、それらを分類します。

[~, maxIndex] = max(YPred2, [], 2);
predictedLabels2 = labels(maxIndex);
disp(predictedLabels2)
     Leak      Mechanical Failure      Mechanical Failure      Software Failure      Electronic Failure 

ステートフルな LSTM を使用した MEX の生成

時系列全体を渡して関数 predict を使って単一のステップで予測する代わりに、関数predictAndUpdateStateを使用して一度に 1 つのタイムステップでストリーミングし、入力の予測を実行できます。この関数は、入力を受け入れ、出力予測を生成し、ネットワークの内部状態を更新して、将来の予測でこの初期入力が考慮されるようにします。

エントリポイント関数 lstm_predict_and_update.m は、単一のタイムステップ入力を受け入れ、関数 predictAndUpdateState を使用して入力を処理します。predictAndUpdateState は、入力タイムステップについての予測を出力し、ネットワークを更新して、以降の入力が同じサンプルに続くタイムステップとして扱われるようにします。すべてのタイムステップを 1 つずつ渡した場合、結果の出力は、すべてのタイムステップが単一の入力として渡された場合と同じになります。

type('lstm_predict_and_update.m')
function out = lstm_predict_and_update(in)
%#codegen

%   Copyright 2020 The MathWorks, Inc.

    persistent mynet;

    if isempty(mynet)
        mynet = coder.loadDeepLearningNetwork('textClassifierNetwork.mat');
    end

    [mynet, out] = predictAndUpdateState(mynet,in);
end

lstm_predict_and_update のコードを生成します。この関数は、呼び出しごとに単一のタイムステップを受け入れるため、matrixInput を、可変のシーケンス長ではなく固定のシーケンス次元 1 になるように指定します。

matrixInput = coder.typeof(double(0),[1 1]);
codegen -config cfg lstm_predict_and_update -args {matrixInput} -report
Code generation successful: View report

最初の観測値で生成された MEX を実行します。

sequenceLength = size(XNew{1},2);
for i=1:sequenceLength
    inTimeStep = XNew{1}(:,i);
    YPred3 = lstm_predict_and_update_mex(inTimeStep);
end
clear mex;

確率が最も高いインデックスを見つけて、ラベルにマッピングします。

[~, maxIndex] = max(YPred3);
predictedLabels3 = labels(maxIndex);
disp(predictedLabels3)
     Leak 

参考

(MATLAB Coder) | (Text Analytics Toolbox) | (MATLAB Coder) | (MATLAB Coder)

関連するトピック