Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

深層学習ネットワークのコード生成

この例では、深層学習を使用するイメージ分類用途のコード生成を実行する方法を説明します。codegen コマンドを使用し、MobileNet-v2、ResNet、GoogLeNet などのイメージ分類ネットワークを使用して予測を実行する MEX 関数を生成します。

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

必須

この例では、CUDA® MEX を生成します。以下のサードパーティ要件が適用されます。

  • CUDA 対応 NVIDIA® GPU および互換性のあるドライバー。

オプション

スタティック ライブラリ、ダイナミック ライブラリ、または実行可能ファイルなどの MEX 以外のビルドについて、この例では以下の要件も適用されます。

GPU 環境の検証

関数coder.checkGpuInstall (GPU Coder)を使用して、この例を実行するのに必要なコンパイラおよびライブラリが正しく設定されていることを検証します。

envCfg = coder.gpuEnvConfig('host');
envCfg.DeepLibTarget = 'cudnn';
envCfg.DeepCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

エントリポイント関数 mobilenetv2_predict

MobileNet-v2 は、ImageNet データベースの 100 万個を超えるイメージで学習済みの畳み込みニューラル ネットワークです。このネットワークは、深さが 155 層であり、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マウス、鉛筆、多くの動物など) に分類できます。ネットワークのイメージ入力サイズは 224 x 224 です。関数analyzeNetworkを使用して、深層学習ネットワーク アーキテクチャを対話的に可視化して表示します。

net = mobilenetv2();
analyzeNetwork(net);

エントリポイント関数 mobilenetv2_predict.m は、イメージ入力を受け取り、事前学習済み MobileNet-v2 畳み込みニューラル ネットワークを使用して、イメージについて予測を実行します。この関数は永続オブジェクト mynet を使用して系列ネットワーク オブジェクトを読み込み、それ以降の呼び出しではこの永続オブジェクトを予測に再利用します。

type('mobilenetv2_predict.m')
% Copyright 2017-2019 The MathWorks, Inc.

function out = mobilenetv2_predict(in) 
%#codegen

persistent mynet;

if isempty(mynet)
    mynet = coder.loadDeepLearningNetwork('mobilenetv2','mobilenetv2');
end

% pass in input   
out = mynet.predict(in);

MEX コード生成の実行

エントリポイント関数 mobilenetv2_predict 用の CUDA コードを生成するには、MEX ターゲットの GPU コード構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数 coder.DeepLearningConfig (GPU Coder) を使用して CuDNN 深層学習構成オブジェクトを作成し、それを GPU コード構成オブジェクトの DeepLearningConfig プロパティに割り当てます。codegen コマンドを実行し、入力サイズを [224,224,3] に指定します。この値は MobileNet-v2 ネットワークの入力層サイズに対応します。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg mobilenetv2_predict -args {ones(224,224,3)} -report
Code generation successful: View report

生成されたコードの説明

系列ネットワークは、155 個の層クラスから成る配列と、ネットワークの設定、予測の呼び出し、クリーンアップを行う関数を含む C++ クラスとして生成されます。

class b_mobilenetv2_0
{
   .... 
   public:
     b_mobilenetv2_0();
     void setup();
     void predict();
     void cleanup();
     ~b_mobilenetv2_0();
};

このクラスの setup() メソッドは、ハンドルを設定し、ネットワーク オブジェクトの各層にメモリを割り当てます。predict() メソッドは、ネットワーク内の 155 個の層それぞれについて予測を実行します。

生成されたコード ファイル mobilenetv2_predict.cu 内のエントリポイント関数 mobilenetv2_predict() は、b_mobilenetv2 クラス型の静的オブジェクトを構築し、このネットワーク オブジェクトに対して setup や predict を呼び出します。

static b_mobilenetv2_0 mynet;
static boolean_T mynet_not_empty;
/* Function Definitions */
void mobilenetv2_predict(const real_T in[150528], real32_T out[1000])
{
  if (!mynet_not_empty) {
    DeepLearningNetwork_setup(&mynet);
    mynet_not_empty = true;
  }
   /*  pass in input    */
   DeepLearningNetwork_predict(&mynet, in, out);
 }

バイナリ ファイルは、ネットワーク内の全結合層や畳み込み層などのパラメーターを持つ層に対してエクスポートされます。たとえば、ファイル cnn_mobilenetv2_conv*_w および cnn_mobilenetv2_conv*_b は、ネットワーク内の畳み込み層の重みとバイアス パラメーターに対応します。生成されたファイルのリストを表示するには、次を使用します。

dir(fullfile(pwd, 'codegen', 'mex', 'mobilenetv2_predict'))

生成された MEX の実行

入力イメージを読み込みます。

im = imread('peppers.png');
imshow(im);

入力イメージに対して mobilenetv2_predict_mex を呼び出します。

im = imresize(im, [224,224]);
predict_scores = mobilenetv2_predict_mex(double(im));

上位 5 つの予測スコアとそのラベルを取得します。

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use MobileNet-v2')

メモリに読み込まれた静的ネットワーク オブジェクトをクリアします。

clear mex;

ResNet-50 ネットワークを使用したイメージの分類

DAG ネットワーク ResNet-50 を使用してイメージを分類することもできます。MATLAB® 用の事前学習済み ResNet-50 モデルは、Deep Learning Toolbox™ の ResNet-50 サポート パッケージに含まれています。このサポート パッケージをダウンロードしてインストールするには、アドオン エクスプローラーを使用します。アドオンの検索とインストールの詳細については、アドオンの取得と管理を参照してください。

net = resnet50;
disp(net)
  DAGNetwork with properties:

         Layers: [177×1 nnet.cnn.layer.Layer]
    Connections: [192×2 table]
     InputNames: {'input_1'}
    OutputNames: {'ClassificationLayer_fc1000'}

MEX コード生成の実行

エントリポイント関数 resnet_predict.m の CUDA コードを生成するには、MEX ターゲットの GPU コード構成オブジェクトを作成し、ターゲット言語を C++ に設定します。このエントリポイント関数は関数 resnet50 を呼び出して、ネットワークを読み込み、入力イメージに対して予測を実行します。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg resnet_predict -args {ones(224,224,3)} -report
Code generation successful: View report

入力イメージに対して resnet_predict_mex を呼び出します。

predict_scores = resnet_predict_mex(double(im));

上位 5 つの予測スコアとそのラベルを取得します。

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use ResNet-50')

メモリに読み込まれた静的ネットワーク オブジェクトをクリアします。

clear mex;

GoogLeNet (Inception) ネットワークを使用したイメージの分類

MATLAB 用の事前学習済み GoogLeNet モデルは、Deep Learning Toolbox の GoogLeNet サポート パッケージに含まれています。このサポート パッケージをダウンロードしてインストールするには、アドオン エクスプローラーを使用します。アドオンの検索とインストールの詳細については、アドオンの取得と管理を参照してください。

net = googlenet;
disp(net)
  DAGNetwork with properties:

         Layers: [144×1 nnet.cnn.layer.Layer]
    Connections: [170×2 table]
     InputNames: {'data'}
    OutputNames: {'output'}

MEX コード生成の実行

エントリポイント関数 googlenet_predict.m の CUDA コードを生成します。このエントリポイント関数は関数 googlenet を呼び出して、ネットワークを読み込み、入力イメージに対して予測を実行します。このエントリポイント関数のコードを生成するには、MEX ターゲットの GPU 構成オブジェクトを作成します。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg googlenet_predict -args {ones(224,224,3)} -report
Code generation successful: View report

入力イメージに対して googlenet_predict_mex を呼び出します。

im = imresize(im, [224,224]);
predict_scores = googlenet_predict_mex(double(im));

上位 5 つの予測スコアとそのラベルを取得します。

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use GoogLeNet')

メモリに読み込まれた静的ネットワーク オブジェクトをクリアします。

clear mex;

関連するトピック