Main Content

MobileNet-v2 ネットワークのコード生成と Raspberry Pi への展開

この例では、MobileNet-v2 事前学習済みネットワークを使用してオブジェクト予測を行う C++ コードを生成して展開する方法を説明します。

必要条件

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

  • ARM Compute Library (ターゲット ARM ハードウェア上)

  • Open Source Computer Vision Library (OpenCV) v2.4 (ターゲット ARM ハードウェア上)

  • コンパイラおよびライブラリの環境変数

  • MATLAB® Coder™

  • MATLAB Coder Interface for Deep Learning Libraries サポート パッケージ

  • Deep Learning Toolbox™

  • Deep Learning Toolbox Model for MobileNet-v2 Network サポート パッケージ

  • Image Processing Toolbox™

  • MATLAB Support Package for Raspberry Pi Hardware

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

この例は MATLAB Online ではサポートされていません。

この例では、DAG ネットワーク MobileNet-v2 を使用して、ARM® Compute Library を用いたイメージ分類を実行します。MATLAB 用の事前学習済み MobileNet-v2 ネットワークは、Deep Learning Toolbox Model for MobileNet-v2 Network サポート パッケージに含まれています。

ARM Compute Library とハードウェア サポート パッケージを使用するコードを生成する場合、codegen はホスト コンピューター上でコードを生成し、生成されたファイルをターゲット ハードウェアにコピーして、ターゲット ハードウェアで実行可能ファイルをビルドします。

関数 mobilenet_predict のコード生成の構成

関数 mobilenet_predict は、入力イメージに対して MobileNet-v2 ネットワーク オブジェクトの predict メソッドを呼び出し、予測スコアの出力を返します。関数は coder.updateBuildInfo を呼び出して、生成された makefile のリンク オプションを指定します。

type mobilenet_predict
function out = mobilenet_predict(in)

persistent net;
opencv_linkflags = '`pkg-config --cflags --libs opencv`';
coder.updateBuildInfo('addLinkFlags',opencv_linkflags);
if isempty(net)
    net = coder.loadDeepLearningNetwork('mobilenetv2', 'mobilenet');
end

out = net.predict(in);

end

C++ コード生成構成オブジェクトを作成します。

cfg = coder.config('exe');
cfg.TargetLang = 'C++';

ARM Compute Library の使用を指定します。ARM Compute Library は、Raspberry Pi ハードウェアに最適化された機能を提供します。ARM Compute Library を使用するコードを生成するには、coder.ARMNEONConfig オブジェクトを作成します。Raspberry Pi にインストールされている ARM Compute Library のバージョンと Raspberry Pi のアーキテクチャを指定します。コード生成構成オブジェクトに深層学習構成オブジェクトを追加します。

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

Raspberry Pi への接続の作成

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

  • raspiname: 自分の Raspberry Pi のホスト名

  • username: 自分のユーザー名

  • password: 自分のパスワード

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

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

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

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

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

buildDir = '~/remoteBuildDir';
cfg.Hardware.BuildDir = buildDir;

C++ メイン ファイルの指定

コード生成構成オブジェクトでメイン ファイル main_mobilenet.cpp を指定します。ファイルは関数 mobilenet_predict 用に生成された C++ コードを呼び出します。ファイルは、入力イメージを読み取り、そのデータを生成された関数呼び出しに渡し、イメージに対する予測を取得し、予測スコアをファイルに出力します。

cfg.CustomSource = 'main_mobilenet.cpp';

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

C++ コードを生成します。codegen と MATLAB Support Package for Raspberry Pi Hardware を使用する場合、実行可能ファイルは Raspberry Pi でビルドされます。

コードを生成するには、Raspberry Pi で 環境変数 (MATLAB Coder) ARM_COMPUTELIBLD_LIBRARY_PATH を設定しなければなりません。

codegen -config cfg mobilenet_predict -args {ones(224, 224, 3,'single')} -report

生成された実行可能ファイルのフォルダーの取得

生成コードを Raspberry Pi 上でテストするには、入力イメージを生成コードのフォルダーにコピーします。このフォルダーは手動で、または raspi.utils.getRemoteBuildDirectory API を使用して見つけることができます。この関数は、codegen を使用して生成されたバイナリ ファイルのフォルダーをリストします。バイナリが 1 つのフォルダーでのみ見つかったと仮定して、次を入力します。

applicationDirPaths = raspi.utils.getRemoteBuildDirectory('applicationName','mobilenet_predict');
targetDirPath = applicationDirPaths{1}.directory;

Raspberry Pi へのサンプル ファイルのコピー

実行可能プログラムを実行するのに必要なファイルをコピーするには、putFile を使用します。

r.putFile('peppers_raspi_mobilenet.png',targetDirPath);

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

MATLAB から Raspberry Pi で実行可能プログラムを実行し、出力を MATLAB に戻します。

exeName = 'mobilenet_predict.elf';
argsforexe = ' peppers_raspi_mobilenet.png '; % Provide the input image;
command = ['cd ' targetDirPath ';sudo ./' exeName argsforexe];
output = system(r,command);

ネットワークの 1000 個の出力クラスについての予測スコアの取得

outputfile = [targetDirPath, '/output.txt'];
r.getFile(outputfile);

ラベルへの予測スコアのマッピングおよび出力の表示

上位 5 つの予測スコアを学習済みネットワークの対応するラベルにマッピングし、出力を表示します。

type mapPredictedScores_mobilenet
%% Map the Prediction Scores to Labels and Display Output
net = mobilenetv2;
ClassNames = net.Layers(end).ClassNames;

%% Read the classification
fid = fopen('output.txt') ;
S = textscan(fid,'%s');
fclose(fid) ;
S = S{1} ;
predict_scores = cellfun(@(x)str2double(x), S);

%% Remove NaN values that were strings
predict_scores(isnan(predict_scores))=[];
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
top5labels = ClassNames(indx(1:5));

%% Display classification labels on the image
im = imread('peppers_raspi_mobilenet.png');
im = imresize(im, [224 224]);
outputImage = zeros(224,400,3, 'uint8');
for k = 1:3
    outputImage(:,177:end,k) = im(:,:,k);
end
scol = 1;
srow = 1;
outputImage = insertText(outputImage, [scol, srow], 'Classification with MobileNetv2', 'TextColor', 'w','FontSize',20, 'BoxColor', 'black');
srow = srow + 30;
for k = 1:5
    outputImage = insertText(outputImage, [scol, srow], [top5labels{k},' ',num2str(scores(k), '%2.2f'),'%'], 'TextColor', 'w','FontSize',15, 'BoxColor', 'black');
    srow = srow + 25;
end
imshow(outputImage);

参考

(MATLAB Coder) | (MATLAB Coder) | (MATLAB Coder)

関連するトピック