Main Content

codegen を使用した ARM Compute による深層学習の予測

この例では、codegen を使用し、ARM® プロセッサで深層学習を使用するロゴ分類アプリケーションのコードを生成する方法を説明します。ロゴ分類アプリケーションは、dlnetwork オブジェクトを使用してイメージからのロゴ認識を実行します。生成コードはコンピューター ビジョンおよび機械学習用の ARM Compute Library を利用します。

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

  • NEON 拡張をサポートする ARM プロセッサ

  • Open Source Computer Vision Library (OpenCV) v3.1

  • ARM Compute および OpenCV ライブラリの環境変数

この例で使用されている ARM Compute Library のバージョンは、コード生成でサポートされている最新バージョンではない可能性があります。サポートされるライブラリのバージョン、および環境変数の設定の詳細については、深層学習に MATLAB Coder を使用するための前提条件 (MATLAB Coder)を参照してください。

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

事前学習済みの SeriesNetwork の取得

事前学習済みの LogoNet ネットワークをダウンロードして、これが存在しない場合は logonet.mat という名前で保存します。このネットワークは MATLAB® で開発されたもので、アーキテクチャは AlexNet と似ています。このネットワークはさまざまなライティング条件とカメラの角度の下で 32 個のロゴを認識できます。

net = getLogonet();

SeriesNetwork ネットワーク オブジェクトを dlnetwork オブジェクトに変換し、ネットワークを MAT ファイルに保存します。

dlconvnet = dag2dlnetwork(net);
save dlLogoNet.mat dlconvnet

ネットワークには、畳み込み層、全結合層、分類出力層など、22 個の層が含まれています。ネットワーク アーキテクチャを表示するには、関数analyzeNetworkを使用します。

analyzeNetwork(dlconvnet)

環境変数の設定

ARM ターゲット ハードウェアで、ARM_COMPUTELIB が設定されていて LD_LIBRARY_PATH に ARM Compute Library フォルダーへのパスが含まれていることを確認します。

エントリポイント関数 logonet_predict

エントリポイント関数 logonet_predict.m は、イメージ入力を受け取り、dlLogoNet.mat ファイルに保存されている深層学習ネットワークを使用して、イメージについて予測を実行します。この関数は、dlLogoNet.mat からネットワーク オブジェクトを永続変数 dlLogonet に読み込み、それ以降の予測の呼び出しでこの永続変数を再利用します。dlarray オブジェクトは関数内で作成され、関数への入力と出力のデータ型はプリミティブ型になります。

type logonet_predict
function out = logonet_predict(in)
%#codegen

% Copyright 2017-2023 The MathWorks, Inc.

% A persistent object dlLogonet is used to load the network object. At the
% first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is
% reused to call predict on inputs, thus avoiding reconstructing and
% reloading the network object.

dlIn = dlarray(in, 'SSC');

persistent dlLogonet;

if isempty(dlLogonet)
   
    dlLogonet = coder.loadDeepLearningNetwork('dlLogoNet.mat','dlLogonet');

end

dlOut = predict(dlLogonet, dlIn);

out = extractdata(dlOut);

end

C++ ソース コードの生成

ハードウェア サポート パッケージを使用せずに ARM ベースのデバイス向けのコードを生成する場合、ライブラリ用の構成オブジェクトを作成します。実行可能プログラム用の構成オブジェクトは作成しません。

スタティック ライブラリのための構成オブジェクトを作成します。ターゲット言語は C++ に設定し、コードのみを生成するようにします。

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.GenCodeOnly = true;

coder.ARMNEONConfig オブジェクトを作成します。ターゲット ARM プロセッサのライブラリ バージョンとアーキテクチャを指定します。たとえば、ターゲット ボードが ARMv8 アーキテクチャと ARM Compute Library バージョン 20.02.1 を備えた HiKey/Rock960 ボードであるとします。

dlcfg = coder.DeepLearningConfig('arm-compute');
dlcfg.ArmComputeVersion = '20.02.1';
dlcfg.ArmArchitecture = 'armv8';

コード生成構成オブジェクトに深層学習構成オブジェクトを追加します。codegen コマンドを使用してソース コードを生成します。

cfg.DeepLearningConfig = dlcfg;
codegen -config cfg logonet_predict -args {ones(227, 227, 3, 'single')} -d arm_compute
Code generation successful.

コードは、ホスト コンピューターの現在の作業フォルダーにある arm_compute フォルダーに生成されます。

関数 packNGo を使用した zip ファイルの生成

関数 packNGo は、すべての関連ファイルを zip 圧縮ファイルにパッケージ化します。

zipFileName = 'arm_compute.zip';
bInfo = load(fullfile('arm_compute','buildInfo.mat'));
packNGo(bInfo.buildInfo, {'fileName', zipFileName,'minimalHeaders', false, 'ignoreFileMissing',true});

生成された zip ファイルのターゲット ハードウェアへのコピー

zip ファイルをフォルダーにコピーして解凍します。ターゲット ハードウェアから zip ファイルを削除します。

以下のコマンドで、次を置き換えます。

  • password: 自分のパスワード

  • username: 自分のユーザー名

  • targetname: 自分のデバイスの名前

  • targetloc: ファイルの保存先フォルダー

Linux から zip ファイルをコピーして解凍するには、以下のコマンドを実行します。

if isunix, system(['sshpass -p password scp -r '  fullfile(pwd,zipFileName) ' username@targetname:targetloc/']), end
if isunix, system('sshpass -p password ssh username@targetname "if [ -d targetloc/arm_compute ]; then rm -rf targetloc/arm_compute; fi"'), end
if isunix, system(['sshpass -p password ssh username@targetname "unzip targetloc/' zipFileName ' -d targetloc/arm_compute"']), end
if isunix, system(['sshpass -p password ssh username@targetname "rm -rf  targetloc' zipFileName '"']), end

Windows から zip ファイルをコピーして解凍するには、以下のコマンドを実行します。

if ispc, system(['pscp.exe -pw password -r '  fullfile(pwd,zipFileName) ' username@targetname:targetloc/']), end
if ispc, system('plink.exe -l username -pw password targetname "if [ -d targetloc/arm_compute ]; then rm -rf targetloc/arm_compute; fi"'), end
if ispc, system(['plink.exe -l username -pw password targetname "unzip targetloc/' zipFileName ' -d targetloc/arm_compute"']), end
if ispc, system(['plink.exe -l username -pw password targetname "rm -rf  targetloc' zipFileName '"']), end

サンプル ファイルのターゲット ハードウェアへのコピー

以下のサポート ファイルをホスト コンピューターからターゲット ハードウェアにコピーします。

  • 入力イメージ (coderdemo_google.png)

  • ライブラリを生成するための makefile (logonet_predict_rtw.mk)

  • 実行可能プログラムをビルドするための makefile (makefile_arm_logo.mk)

  • synset ディクショナリ (synsetWordsLogoDet.txt)

以下のコマンドで、次を置き換えます。

  • password: 自分のパスワード

  • username: 自分のユーザー名

  • targetname: 自分のデバイスの名前

  • targetloc: ファイルの保存先フォルダー

Linux から実行する場合、以下の手順を実行して必要なファイルをすべてコピーします。

if isunix, system('sshpass -p password scp logonet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp coderdemo_google.png username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp makefile_arm_logo.mk username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp synsetWordsLogoDet.txt username@targetname:targetloc/arm_compute/'), end

Windows から実行する場合、以下の手順を実行して必要なファイルをすべてコピーします。

if ispc, system('pscp.exe -pw password logonet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password coderdemo_google.png username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password makefile_arm_logo.mk username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password synsetWordsLogoDet.txt username@targetname:targetloc/arm_compute/'), end

ターゲット ハードウェアでのライブラリのビルド

ターゲット ハードウェアでライブラリをビルドするには、生成された makefile を ARM ハードウェアで実行します。

ターゲット ハードウェアで環境変数 ARM_COMPUTELIB と LD_LIBRARY_PATH が設定されていることを確認します。変数 ARM_ARCH は、ARM アーキテクチャに基づいてコンパイラ フラグを渡すために makefile で使用されます。変数 ARM_VER は、ARM Compute のバージョンに基づいてコードをコンパイルするために makefile で使用されます。以下のコマンドのハードウェア資格情報とパスを、前の節と同様に置き換えます。

Linux からライブラリをビルドするには、以下の手順を実行します。

if isunix, system('sshpass -p password scp main_arm_logo.cpp username@targetname:targetloc/arm_compute/'), end
if isunix, system(['sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f logonet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end

Windows からライブラリをビルドするには、以下の手順を実行します。

if ispc, system('pscp.exe -pw password main_arm_logo.cpp username@targetname:targetloc/arm_compute/'), end
if ispc, system(['plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f logonet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end

ターゲット ハードウェアでのライブラリからの実行可能ファイルを作成

ソースのメイン ラッパー ファイルを使用してライブラリをビルドし、実行可能ファイルを作成します。main_arm_logo.cpp は、関数 logonet_predict を呼び出す C++ メイン ラッパー ファイルです。

Linux から実行可能ファイルを作成するには、以下のコマンドを実行します。

if isunix, system('sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f makefile_arm_logo.mk targetDirName=targetloc/arm_compute"'), end

Windows から実行可能ファイルを作成するには、以下のコマンドを実行します。

if ispc, system('plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f makefile_arm_logo.mk targetDirName=targetloc/arm_compute"'), end

ターゲット ハードウェア上での実行可能ファイルの実行

以下のコマンドを使用して、Linux から実行可能ファイルを実行します。

if isunix, system('sshpass -p password ssh username@targetname "cd targetloc/arm_compute/; ./logonet coderdemo_google.png"'), end

以下のコマンドを使用して、Windows から実行可能ファイルを実行します。

if ispc, system('plink.exe -l username -pw password targetname "cd targetloc/arm_compute/; ./logonet coderdemo_google.png"'), end
Top 5 Predictions:
-----------------------------
99.992% google
0.003% corona
0.003% singha
0.001% esso
0.000% fedex

coderdemo_google.png