ARM Compute Library を使用した、深層学習ネットワークのためのコード生成
MATLAB® Coder™ を使用して、NEON 拡張をサポートする ARM® プロセッサを使用する組み込みプラットフォームをターゲットとする、既に学習済みのニューラル ネットワークからの予測のためのコードを生成できます。コード ジェネレーターは、コンピューター ビジョンおよび機械学習に ARM Compute Library を利用します。生成されたコードは、入力 SeriesNetwork (Deep Learning Toolbox) または DAGNetwork (Deep Learning Toolbox) ネットワーク オブジェクトで指定されたアーキテクチャ、レイヤー、およびパラメーターをもつニューラル ネットワークを実装します。
次のいずれかの方法を使用してコードを生成します。
必要条件
MATLAB Coder Interface for Deep Learning。サポート パッケージをインストールするには、これを MATLAB の [アドオン] メニューから選択します。
コンピューター ビジョンと機械学習用の ARM Compute Library をターゲット ハードウェアにインストールしなければなりません。
Deep Learning Toolbox™.
コンパイラおよびライブラリの環境変数。
メモ
このヘルプ トピックの例で使用する ARM Compute Library のバージョンは、コード生成でサポートされている最新バージョンではない可能性があります。サポートされているライブラリのバージョンと、環境変数の設定に関する詳細については、深層学習に MATLAB Coder を使用するための前提条件を参照してください。
codegen を使用したコード生成
codegen を使用して ARM ターゲットで深層学習のコードを生成するには、次を行います。
事前学習済みの畳み込みニューラル ネットワーク (CNN) を読み込んで
predictを呼び出すエントリポイント関数を作成します。以下に例を示します。function out = squeezenet_predict(in) %#codegen persistent net; opencv_linkflags = '`pkg-config --cflags --libs opencv`'; coder.updateBuildInfo('addLinkFlags',opencv_linkflags); if isempty(net) net = coder.loadDeepLearningNetwork('squeezenet', 'squeezenet'); end out = net.predict(in); end
ターゲット ハードウェアが Raspberry Pi® である場合、MATLAB Support Package for Raspberry Pi Hardware を活用することができます。サポート パッケージを使用すると、
codegenは生成コードを Raspberry Pi に移動させて、Raspberry Pi で実行可能プログラムをビルドします。ハードウェア サポート パッケージをもっていないターゲット用にコードを生成する場合、コマンドを実行して、生成されたファイルを移動させ、実行可能プログラムを作成しなければなりません。ARM ターゲットでは、MEX 生成による深層学習用のコード生成はサポートされていません。
ARM については、複数のイメージまたは観測値 (
N > 1) をもつpredict(Deep Learning Toolbox) への入力について、1 より大きいMiniBatchSizeはサポートされません。1 のMiniBatchSizeを指定します。
Raspberry Pi での深層学習用のコード生成
MATLAB Support Package for Raspberry Pi Hardware がある場合、Raspberry Pi で深層学習用のコードを生成するには、次を行います。
Raspberry Pi に接続するには、
raspiを使用します。以下に例を示します。r = raspi('raspiname','username','password');
coder.configを使用して、ライブラリまたは実行可能ファイル用のコード生成構成オブジェクトを作成します。TargetLangプロパティを'C++'に設定します。cfg = coder.config('exe'); cfg.TargetLang = 'C++';
coder.DeepLearningConfigを使用して、深層学習構成オブジェクトを作成します。ArmComputeVersionおよびArmArchitectureプロパティを設定します。コード生成構成オブジェクトのDeepLearningConfigプロパティをcoder.ARMNEONConfigオブジェクトに設定します。以下に例を示します。dlcfg = coder.DeepLearningConfig('arm-compute'); dlcfg.ArmArchitecture = 'armv7'; dlcfg.ArmComputeVersion = '20.02.1'; cfg.DeepLearningConfig = dlcfg;
Raspberry Pi のコード生成ハードウェア設定を構成するには、
coder.hardwareを使用してcoder.Hardwareオブジェクトを作成します。コード生成構成オブジェクトのHardwareプロパティをcoder.Hardwareオブジェクトに設定します。hw = coder.hardware('Raspberry Pi'); cfg.Hardware = hw;実行可能プログラムを生成している場合は、C++ メイン プログラムを指定します。以下に例を示します。
cfg.CustomSource = 'main.cpp';コードを生成するには、
codegenを使用します。-configオプションを使用して、コード生成構成オブジェクトを指定します。以下に例を示します。codegen -config cfg squeezenet_predict -args {ones(227, 227, 3,'single')} -report
メモ
コード生成では半精度入力を指定できます。ただし、コード ジェネレーターによって入力が単精度に型キャストされます。Deep Learning Toolbox は、MATLAB でのすべての計算に単精度浮動小数点演算を使用します。
ハードウェア サポート パッケージがない場合のコード生成
ターゲット用のハードウェア サポート パッケージがない場合に深層学習用のコードを生成するには、次を行います。
Linux® ホストでのみコードを生成します。
ライブラリ用の構成オブジェクトを作成します。以下に例を示します。
cfg = coder.config('lib');実行可能プログラムに対して構成オブジェクトを使用しないでください。
C++ コードおよびソース コードのみを生成するように、コード生成を設定します。
cfg.GenCodeOnly = true; cfg.TargetLang = 'C++';ARM Compute Library を使用したコード生成を指定するには、
coder.DeepLearningConfigを使用してcoder.ARMNEONConfigオブジェクトを作成します。ArmComputeVersionおよびArmArchitectureプロパティを設定します。コード生成構成オブジェクトのDeepLearningConfigプロパティをcoder.ARMNEONConfigオブジェクトに設定します。dlcfg = coder.DeepLearningConfig('arm-compute'); dlcfg.ArmArchitecture = 'armv7'; dlcfg.ArmComputeVersion = '20.02.1'; cfg.DeepLearningConfig = dlcfg;
ターゲット ハードウェアに固有のコード生成パラメーターを設定するには、
HardwareImplementationオブジェクトのProdHWDeviceTypeプロパティを設定します。ARMv7 アーキテクチャの場合、
'ARM Compatible->ARM Cortex'を使用します。ARMv8 アーキテクチャの場合、
'ARM Compatible->ARM 64-bit (LP64)'を使用します。
以下に例を示します。
cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM 64-bit (LP64)';コードを生成するには、
codegenを使用します。-configオプションを使用して、コード生成構成オブジェクトを指定します。以下に例を示します。codegen -config cfg squeezenet_predict -args {ones(227, 227, 3, 'single')} -d arm_compute
例については、SqueezeNet ネットワークのコード生成と Raspberry Pi への展開を参照してください。
生成コード
系列ネットワークは、層のクラスの配列を含む C++ クラスとして生成されます。
class b_squeezenet_0
{
public:
int32_T batchSize;
int32_T numLayers;
real32_T *inputData;
real32_T *outputData;
MWCNNLayer *layers[68];
private:
MWTargetNetworkImpl *targetImpl;
public:
b_squeezenet_0();
void presetup();
void postsetup();
void setup();
void predict();
void cleanup();
real32_T *getLayerOutput(int32_T layerIndex, int32_T portIndex);
~b_squeezenet_0();
};
このクラスの setup() メソッドは、ハンドルを設定し、ネットワーク オブジェクトの各層にメモリを割り当てます。predict() メソッドは、ネットワークの各層の予測を呼び出します。エントリポイント関数 squeezenet_predict のコードを生成するとします。生成された "ユーザー用" のファイル squeezenet_predict.cpp では、エントリポイント関数 squeeznet_predict() によって b_squeezenet_0 クラス タイプのスタティック オブジェクトが作成され、ネットワーク オブジェクトに対して setup および predict が呼び出されます。
static b_squeezenet_0 net;
static boolean_T net_not_empty;
// Function Definitions
//
// A persistent object net is used to load the DAGNetwork object.
// At the first call to this function, the persistent object is constructed and
// set up. When the function is called subsequent times, the same object is reused
// to call predict on inputs, avoiding reconstructing and reloading the
// network object.
// Arguments : const real32_T in[154587]
// real32_T out[1000]
// Return Type : void
//
void squeezenet_predict(const real32_T in[154587], real32_T out[1000])
{
// Copyright 2018 The MathWorks, Inc.
if (!net_not_empty) {
DeepLearningNetwork_setup(&net);
net_not_empty = true;
}
DeepLearningNetwork_predict(&net, in, out);
}
バイナリ ファイルは、パラメーターをもつ層 (ネットワークの全結合層および畳み込み層など) に対してエクスポートされます。たとえば、cnn_squeezenet_*_w および cnn_squeezenet_*_b というパターンの名前をもつファイルは、ネットワークの畳み込み層の重みパラメーターおよびバイアス パラメーターに対応します。
cnn_squeezenet_conv10_b cnn_squeezenet_conv10_w cnn_squeezenet_conv1_b cnn_squeezenet_conv1_w cnn_squeezenet_fire2-expand1x1_b cnn_squeezenet_fire2-expand1x1_w cnn_squeezenet_fire2-expand3x3_b cnn_squeezenet_fire2-expand3x3_w cnn_squeezenet_fire2-squeeze1x1_b cnn_squeezenet_fire2-squeeze1x1_w ...
int8 コードの生成
深層学習ネットワークの int8 コードの生成を参照してください。
MATLAB Coder アプリを使用したコード生成
[ソース ファイルの選択] ステップと [入力の型を定義] ステップを完了します。
[コード生成] ステップに進みます (ARM Compute Library を使用したコード生成では MEX 生成はサポートされていないため、[実行時の問題の確認] ステップはスキップします)。
[言語] を [C++] に設定します。
ターゲット ARM ハードウェアを指定します。
ターゲット ハードウェアが Raspberry Pi で、MATLAB Support Package for Raspberry Pi Hardware をインストールしている場合は、次を行います。
[ハードウェア ボード] に対して
[Raspberry Pi]を選択します。Raspberry Pi 設定にアクセスするには、[詳細設定] をクリックします。次に、[ハードウェア] をクリックします。[Device Address]、[ユーザー名]、[パスワード]、および [ビルド ディレクトリ] を指定します。
ARM ターゲットのサポート パッケージがない場合は、次を行います。
[ビルド タイプ] が
[スタティック ライブラリ]または[ダイナミック ライブラリ]であることを確認し、[コード生成のみ] チェック ボックスをオンにします。[ハードウェア ボード] では
[なし - 以下のデバイスを選択]を選択します。[デバイス ベンダー] では
[ARM Compatible]を選択します。[デバイス タイプ] に対しては、次のとおりです。
ARMv7 アーキテクチャの場合、
[ARM Cortex]を選択します。ARMv8 アーキテクチャの場合、
[ARM 64-bit (LP64)]を選択します。
メモ
ARM ターゲットで深層学習用のコードを生成して、ハードウェア サポート パッケージを使用しない場合は、コードを Linux ホスト上でのみ生成します。
[深層学習] ペインで、[ターゲット ライブラリ] を
[ARM Compute]に設定します。[ARM Compute Library のバージョン] および [ARM Compute アーキテクチャ] を指定します。コードを生成します。
参考
coder.loadDeepLearningNetwork | coder.DeepLearningConfig | coder.ARMNEONConfig