Main Content

Raspberry Pi での信号セグメンテーション ディープ ネットワークの展開

この例では、短時間フーリエ変換と双方向長短期記憶 (BiLSTM) ネットワークを使用した、心電図 (ECG) 信号の波形セグメンテーションのワークフローについて詳しく説明します。また、この例では、Raspberry Pi® ターゲット (ARM® ベースのデバイス) でのセグメンテーション用に、コードを生成してそのコードと学習済み BiLSTM ネットワークを展開する方法についても説明しています。

この例の事前学習済みのネットワークは、深層学習を使用した波形セグメンテーションの例に似ています。

この例の詳細:

  • Raspberry Pi での展開および実行用に MATLAB® から生成されるコードを検証するプロセッサインザループ (PIL) ベースのワークフロー

  • スタンドアロンの実行可能ファイルの生成

PIL 検証プロセスは、設計サイクルの重要な部分であり、スタンドアロンの実行可能ファイルを展開する前に、生成コードの動作が設計と一致することを確認します。

ECG データセット

この例では、一般に公開されている QT データベースからの ECG 信号を使用します [1] [2]。データは、サンプル レート 250 Hz で合計 105 人の患者から測定された、約 15 分間のラベル付き ECG 記録で構成されています。

ECG 信号は次の心拍形態に分けられます [3]。

  • P 波 — QRS 群が心房性脱分極を表す前の小さいたわみ

  • QRS 群 — 心拍の最大振幅部分

  • T 波 — QRS 群が心室再分極を表した後の小さいたわみ

ECG 波形のこれらの領域のセグメンテーションでは、人間の心臓全体の健康状態と異常の存在を評価する測定値の基準を提供できます。

必要条件

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

生成されたコードの機能

生成された実行可能ファイルの主な機能:

  • 15,000 個の単精度の ECG データ サンプルを入力として使用します。

  • 信号の短時間フーリエ変換を計算します。

  • 出力を標準化および正規化します。

  • 事前学習済みの BiLSTM ネットワークを使用して信号の領域にラベルを付けます。

  • ラベル付きの出力ファイルを生成します。

関数 waveformSegmentation

"最上位" 関数または "基本" 関数とも呼ばれる "エントリポイント" 関数は、コード生成のために定義する関数です。エントリポイント関数は、コード生成を可能にする関数を呼び出し、エントリポイント関数から C/C++ コードを生成できるように定義しなければなりません。エントリポイント関数内のすべての関数は、コード生成をサポートしていなければなりません。

この例では、waveformSegmentation がエントリポイント関数です。ECG 信号を入力として受け取り、それを予測のために学習済みの BiLSTM ネットワークに渡します。関数 performPreprocessing は、生の信号を前処理し、短時間フーリエ変換を適用します。関数 genClassifiedResults は、前処理された信号を予測用のネットワークに渡し、分類結果を表示します。

type waveformSegmentation
function out = waveformSegmentation(in)
%#codegen
persistent net;

if isempty(net)
    net = coder.loadDeepLearningNetwork('trained-network-STFTBILSTM.mat', 'net');
end


preprocessedSignal = performPreprocessing(in);
out = cell(3,1);


for indx = 1:3
  out{indx,1} =  genClassifedResults(net.predict(preprocessedSignal{1,indx}));
end



end

Raspberry Pi への接続の作成

MATLAB Support Package for Raspberry Pi の関数 raspi を使用して、Raspberry Pi への接続を作成します。以下のコードで、次を置き換えます。

  • 'raspiname': 自分の Raspberry Pi の名前

  • 'pi': 自分のユーザー名

  • 'password': 自分のパスワード

r = raspi('raspiname','pi','password');

この例では、コードと設計を検証するための PIL ベースのワークフローを示し、スタンドアロンの実行可能ファイルを作成して展開します。オプションとして、スタンドアロンの実行可能ファイルをすぐに展開したい場合は、PIL の実行を省略してスタンドアロンの実行可能ファイルの作成に進むことができます。

PIL MEX 関数の生成

最初の手順では、関数 waveformSegmentation の MEX 関数を生成するための PIL ベースのワークフローを示します。

スタティック ライブラリ用のコード生成構成オブジェクトの設定

スタティック ライブラリ用のコード構成オブジェクトを作成し、検証モードを 'PIL' に設定します。ターゲット言語を 'C++' に設定します。

cfg = coder.config('lib','ecoder',true);
cfg.VerificationMode = 'PIL';
cfg.TargetLang = 'C++'; 

深層学習コード生成用の構成オブジェクトの設定

coder.ARMNEONConfig オブジェクトを作成します。Raspberry Pi にある ARM Compute Library のバージョンを指定します。Raspberry Pi のアーキテクチャを指定します。(この例では、ARM Compute Library v19.05 が必要です)。

dlcfg = coder.DeepLearningConfig('arm-compute');
dlcfg.ArmComputeVersion = '19.05';
dlcfg.ArmArchitecture = 'armv7';

コード生成構成オブジェクトの DeepLearningConfig プロパティに、深層学習構成オブジェクトを設定します。コード生成で MATLAB ソース コメントが表示されるように構成オブジェクトを設定します。

cfg.DeepLearningConfig = dlcfg;
cfg.MATLABSourceComments = 1;

Raspberry Pi 用のコード生成ハードウェア パラメーターの構成

Raspberry Pi 用の coder.Hardware オブジェクトを作成してコード生成構成オブジェクトに追加します。

hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;

Raspberry Pi 上のビルド フォルダーを指定します。

cfg.Hardware.BuildDir = '~/waveformSegmentation';

関数 codegen を使用した C++ ソース コードの生成

関数 codegen を使用して C++ コードを生成します。MATLAB Support Package for Raspberry Pi Hardware で codegen を使用すると、生成コードがボードにダウンロードされ、そこでコンパイルされます。PIL MEX 関数は、MATLAB と、Raspberry Pi で実行される生成コードとの間で通信をするために生成されます。

環境変数 ARM_COMPUTELIB および LD_LIBRARY_PATH が Raspberry Pi 上で設定されていることを確認します。深層学習に MATLAB Coder を使用するための前提条件 (MATLAB Coder) (MATLAB Coder) を参照してください。

codegen -config cfg waveformSegmentation -args {coder.typeof(single(ones(1,15000)),[1,15000],[0,0])} -report
### Target device has no native communication support. Checking connectivity configuration registrations...
 Deploying code. This may take a few minutes. 
### Target device has no native communication support. Checking connectivity configuration registrations...
### Connectivity configuration for function 'waveformSegmentation': 'Raspberry Pi'
Location of the generated elf : /home/pi/waveformSegmentation/MATLAB_ws/R2020b/C/Users/eshashah/OneDrive_-_MathWorks/Documents/MATLAB/Examples/deeplearning_shared-ex28372959/codegen/lib/waveformSegmentation/pil
Code generation successful: View report

Raspberry Pi での実行可能プログラムの実行

MAT ファイル ecgsignal_test を読み込みます。ファイルには、生成コードをテストできるように、サンプルの ECG 信号が格納されています。

生成された MEX 関数 waveformSegmentation_pil をテスト信号で実行します。

load ecgsignal_test.mat;
out = waveformSegmentation_pil(test);
### Starting application: 'codegen\lib\waveformSegmentation\pil\waveformSegmentation.elf'
    To terminate execution: clear waveformSegmentation_pil
### Launching application waveformSegmentation.elf...

信号と予測ラベルを表示します。

labels = categorical(out{1}(1,2000:3000));
msk = signalMask(labels);
plotsigroi(msk,test(1,2000:3000))
title('Predicted Labels')

PIL MEX 関数の出力を確認した後、関数 waveformSegmentation のスタンドアロンの実行可能ファイルを作成できます。

次の部分では、MATLAB Coder アプリを使用して、予測用のコードからスタンドアロンの実行可能ファイルを生成し、Raspberry Pi に展開するコード生成ワークフローを示します。

MATLAB Coder アプリを使用したスタンドアロンの実行可能ファイルの作成

MATLAB Coder アプリは、MATLAB® コードから C または C++ コードを生成します。ワークフローに基づくユーザー インターフェイスにより、コード生成プロセスを進めることができます。以下の手順では、MATLAB Coder アプリを使用する簡単なワークフローを説明します。詳細については、MATLAB Coder (MATLAB Coder)およびMATLAB Coder アプリを使用した C コードの生成 (MATLAB Coder)を参照してください。

エントリポイント関数ファイルの選択

[アプリ] タブで、ツールストリップの右端にある下矢印をクリックして、アプリ ギャラリーを展開します。[コード生成][MATLAB Coder] をクリックします。[ソース ファイルの選択] ページが開きます。エントリポイント関数の名前である waveformSegmentation を入力または選択します。

[次へ] をクリックして [入力の型を定義] ページに進みます。

入力の型の定義

1.[入力またはグローバルの型を直接入力します] を選択し、入力 in の値を single (1x15000) として設定します。

2.[次へ] をクリックして [コード生成] の手順に進みます。MEX 生成では ARM Compute Library を使用したコード生成がサポートされていないため、[実行時の問題の確認] の手順をスキップします。

コードの生成

1.コード生成のダイアログ ボックスで以下の値を設定します。

  • [ビルド タイプ]Executable (.exe) に設定する

  • [言語]C++ に設定する

  • [ハードウェア ボード]Raspberry Pi に設定する

2.[詳細設定] ボタンをクリックします。

  • [カスタム コード] ペインの追加のソース ファイルで、ecgsegmentation_main.cpp を参照して選択します。C/C++ main 関数の記述の詳細については、生成された C/C++ main 関数の例の構造 (MATLAB Coder)を参照してください。

  • [ハードウェア] ペインで、Raspberry Pi ボードのユーザー名パスワードを設定します。

  • [深層学習] ペインで、[ターゲット ライブラリ]ARM Compute に設定します。[ARM Compute Library のバージョン][ARM Compute アーキテクチャ] を指定します。

3.設定のウィンドウを閉じて、コードを生成します。

4.[次へ] をクリックして [ワークフローの完了] ページに進みます。

生成された実行可能ファイル ディレクトリの取得

コード生成が完了したら、生成されたコードを Raspberry Pi でテストします。最初のステップでは、生成されたコードのディレクトリに、ECG の入力信号をコピーします。このディレクトリを見つけるには、手動で検索するか、raspi.utils.getRemoteBuildDirectory API を使用します。この関数は、関数 codegen を使用して生成されたバイナリ ファイルのディレクトリをリストします。バイナリが 1 つのディレクトリでのみ見つかったと仮定して、次を入力します。

applicationDirPaths = ...

raspi.utils.getRemoteBuildDirectory('applicationName','waveformSegmentation');

targetDirPath = applicationDirPaths{1}.directory;

入力ファイルの Raspberry Pi へのコピー

実行可能プログラムを実行するのに必要なファイルをコピーするには、putFile を使用します。これは、MATLAB Support Package for Raspberry Pi Hardware で提供されています。input.csv ファイルには、展開されたコードをテストするために使用されるサンプル ECG 信号が含まれています。

r.putFile('input.csv',targetDirPath);

input = dlmread('input.csv');

Raspberry Pi での実行可能プログラムの実行

MATLAB から Raspberry Pi 上の実行可能プログラムを実行し、出力ファイルを MATLAB に取得します。入力ファイル名は、実行可能ファイルのコマンド ライン引数として渡す必要があります。

exeName = 'waveformSegmentation.elf'; % Executable name

command = ['cd ' targetDirPath ';./' exeName];

system(r,command)

outputPath = strcat(targetDirPath,'/*.txt');

getFile(r,outputPath)

信号と予測ラベルを表示します。出力は以下の図のようになります。

load ecgsignal_test.mat;

labels = categorical(textread('out.txt','%s')');

msk = signalMask(labels(1,2000:3000));

plotsigroi(msk,test(1,2000:3000))

title('Predicted Labels')

参考文献

[1] McSharry, Patrick E., et al. "A dynamical model for generating synthetic electrocardiogram signals." IEEE® Transactions on Biomedical Engineering. Vol. 50, No. 3, 2003, pp. 289–294.

[2] Laguna, Pablo, Raimon Jané, and Pere Caminal. "Automatic detection of wave boundaries in multilead ECG signals: Validation with the CSE database." Computers and Biomedical Research. Vol. 27, No. 1, 1994, pp. 45–60.

[3] Goldberger, Ary L., Luis A. N. Amaral, Leon Glass, Jeffery M. Hausdorff, Plamen Ch. Ivanov, Roger G. Mark, Joseph E. Mietus, George B. Moody, Chung-Kang Peng, and H. Eugene Stanley. "PhysioBank, PhysioToolkit, and PhysioNet: Components of a New Research Resource for Complex Physiologic Signals." Circulation. Vol. 101, No. 23, 2000, pp. e215–e220. [Circulation Electronic Pages; http://circ.ahajournals.org/content/101/23/e215.full].

参考

アプリ

関数

関連するトピック