Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

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

この例では、Intel Math Kernel Library for Deep Neural Networks (MKL-DNN) を使用する事前学習済みの長短期記憶 (LSTM) ネットワークのコードを生成する方法を示します。この例では、入力 timeseries の各ステップに関する予測を行う MEX 関数を生成します。この例は、2 つの方法について説明します。1 つ目の方法では、標準の LSTM ネットワークを使用します。2 つ目の方法では、同じ LSTM ネットワークのステートフルな動作を利用します。この例では、出荷時のイベントのテキストによる説明を使用します。出荷時のイベントは、電子故障、漏れ、機械故障、ソフトウェア エラーの 4 つのカテゴリのいずれかに分類できます。この例では、事前学習済みの LSTM ネットワークを使用します。ネットワークの学習の詳細については、深層学習を使用したテキスト データの分類 (Text Analytics Toolbox)を参照してください。

サードパーティの前提条件

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

入力の準備

wordEncoding MAT ファイルを読み込みます。この MAT ファイルには、数値インデックスとしてエンコードされたワードが格納されています。このエンコードはネットワークの学習時に実行されました。詳細については、深層学習を使用したテキスト データの分類 (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 を使用して入力 string をトークン化します。

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 ネットワークに渡します。特に、この関数は深層学習を使用したテキスト データの分類 (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 (Deep Learning Toolbox)を使用します。

MEX の生成

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

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

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

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

codegenコマンドを実行して 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);

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

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

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

多数の観測値に対する予測を一度に実行する場合は、観測値をまとめて cell 配列にグループ化し、その cell 配列を予測のために渡すことができます。cell 配列は列の cell 配列でなければならず、各 cell に 1 つの観測値を含めなければなりません。入力のシーケンス長は異なる場合があります。この例では、XNew には 5 つの観測値が含まれています。XNew を入力として受け入れることができる MEX 関数を生成するには、入力型を 5 行 1 列の cell 配列に指定します。各 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 に timeseries 全体を単一のステップで渡す代わりに、一度に 1 つのタイム ステップでストリーミングして関数predictAndUpdateState (Deep Learning Toolbox)を使用することで、入力に対する予測を実行できます。この関数は、入力を受け入れて出力予測を生成し、今後の予測でこの初期入力が考慮されるようにネットワークの内部状態を更新します。

エントリポイント関数 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 のコードを生成します。この関数は呼び出しごとに単一のタイム ステップを受け入れるため、可変のシーケンス長ではなく固定のシーケンス次元 1 をもつように matrixInput を指定します。

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 

参考

| (Text Analytics Toolbox) | |

関連するトピック