メインコンテンツ

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

この例では、事前学習済みの SqueezeNet ネットワーク用に、サードパーティの深層学習ライブラリに依存しない C コードを生成する方法を示します。この例では、プロセッサインザループ (PIL) ワークフローを使用して MEX 関数を生成します。この関数は、MATLAB® から Raspberry Pi™ ハードウェアで生成された実行可能ファイルを呼び出します。

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

  • Raspberry Pi ハードウェア

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

エントリポイント関数 squeezenet_predict

この例では、dlnetwork ネットワーク オブジェクトを使用してイメージ分類を表示します。squeezenet_predict 関数は、imagePretrainedNetworkを使用して、事前学習済みの SqueezeNet ネットワークを永続 dlnetwork オブジェクトに読み込みます。それ以降の呼び出しでは、関数はこのオブジェクトを再利用します。dlarray オブジェクトはエントリポイント関数内で作成され、関数への入力と出力は single データ型になります。詳細については、Code Generation for dlarray (MATLAB Coder)を参照してください。

type squeezenet_predict
function out = squeezenet_predict(in) 
%#codegen
% Copyright 2018-2024 The MathWorks, Inc.

    dlIn = dlarray(in,'SSC');
    
    persistent dlnet;
    if isempty(dlnet)
           dlnet = imagePretrainedNetwork('squeezenet');
    end
    
    dlOut = predict(dlnet, dlIn);
        
    out = extractdata(dlOut);
end

Raspberry Pi への接続の作成

MATLAB Support Package for Raspberry Pi Hardware の関数 raspi を使用して、Raspberry Pi への接続を作成します。

r = raspi;

Raspberry Pi ボードに初めて接続する場合、または別のボードに接続する場合は、コードの次の行を使用して置き換えます。

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

  • username: 自分のユーザー名

  • password: 自分のパスワード

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

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

スタティック ライブラリを生成するために coder.EmbeddedCodeConfig オブジェクトを作成します。PIL ベースの実行を有効にするには、VerificationMode プロパティを 'PIL' に設定します。既定では、DeepLearningConfig プロパティはcoder.DeepLearningCodeConfig (MATLAB Coder)オブジェクトであり、ターゲット ライブラリは 'none'. に設定されています。

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

coder.Hardware オブジェクトを作成し、ターゲット ハードウェアを Raspberry Pi として指定します。cfgHardware プロパティにハードウェア オブジェクトを割り当てます。

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

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

buildDir = '/home/pi/squeezenet_predict';
cfg.Hardware.BuildDir = buildDir;

PIL MEX 関数の生成

入力サイズ 227×227×3 を指定して codegen コマンドを実行します。この値は、SqueezeNet ネットワークの入力層サイズに対応します。

codegen -config cfg squeezenet_predict -args {ones(227, 227, 3, 'single')}
### Connectivity configuration for function 'squeezenet_predict': 'Raspberry Pi'
Location of the generated elf : /home/pi/squeezenet_predict/MATLAB_ws/R2024a/C/EM_Path/ExampleManager/yangzhu.Bdoc.24b/deeplearning_shared-ex98393496/codegen/lib/squeezenet_predict/pil
Code generation successful.

テスト イメージに対する予測の実行

入力イメージを読み込みます。入力イメージに対して squeezenet_predict_pil を呼び出します。

I = imread('coffeemug.png');
I = imresize(I,[227,227]);
output = squeezenet_predict_pil(single(I));
### Starting application: 'codegen\lib\squeezenet_predict\pil\squeezenet_predict.elf'
    To terminate execution: clear squeezenet_predict_pil
### Launching application squeezenet_predict.elf...

出力値に 100 を乗算して、スコアをパーセンテージに変換します。イメージの上位 5 つの分類ラベルを表示します。

[val,indx] = sort(output, 'descend');
scores = val(1:5)*100;
[~,classNames] = imagePretrainedNetwork('squeezenet');
top5labels = classNames(indx(1:5));

outputImage = zeros(227,400,3, 'uint8');
for k = 1:3
    outputImage(:,174:end,k) = I(:,:,k);
end

scol = 1;
srow = 20;

for k = 1:5
        outputImage = insertText(outputImage, [scol, srow], ...
            [top5labels{k},' ',num2str(scores(k), '%2.2f'),'%'], ...
            'TextColor', 'w','FontSize',15, 'BoxColor', 'black');
    srow = srow + 20;
end

imshow(imresize(outputImage,[448,800]));

Figure contains an axes object. The axes object contains an object of type image.

生成された PIL 実行可能ファイルのクリア

clear squeezenet_predict_pil
### Host application produced the following standard output (stdout) and standard error (stderr) messages: