Main Content

NVIDIA TensorRT ライブラリを使用した深層学習予測

この例では、NVIDIA® TensorRT™ ライブラリを使用して深層学習アプリケーションのコードを生成する方法を示します。この例では、codegen コマンドを使用し、TensorRT を使用してロゴ認識分類ネットワークで予測を実行する MEX ファイルを生成します。この例では、codegen コマンドを使用して、8 ビット整数および 16 ビット浮動小数点予測を実行する MEX ファイルを生成する方法も示します。

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

必須

この例では CUDA® MEX を生成します。CUDA 対応 NVIDIA GPU および互換性のあるドライバーが必要です。8 ビット整数および 16 ビット浮動小数点の精度モードを使用するには、特定の GPU Compute Capability を備えていなければなりません。サードパーティ ハードウェアを参照してください。

オプション

静的ライブラリ、動的ライブラリ、実行可能ファイルなどの MEX 以外のビルドについては、以下も必要になります。

GPU 環境の検証

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

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

事前学習済みネットワークのダウンロードと読み込み

この例では、事前学習済みのロゴ認識ネットワークを使用して、イメージ内のロゴを分類します。MathWorks の Web サイトから事前学習済みの LogoNet ネットワークをダウンロードし、ファイルを読み込みます。このネットワークは MATLAB で開発されたもので、サイズは約 42 MB です。このネットワークはさまざまなライティング条件とカメラの角度の下で 32 個のロゴを認識できます。ロゴ認識ネットワークの学習の詳細については、ロゴ認識ネットワークを参照してください。

net = getLogonet;

エントリポイント関数 logonet_predict

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

type('logonet_predict.m')
function out = logonet_predict(in)
%#codegen

% Copyright 2017-2022 The MathWorks, Inc.

% A persistent object logonet 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.
persistent logonet;

if isempty(logonet)
    
    logonet = coder.loadDeepLearningNetwork('LogoNet.mat','logonet');

end

out = logonet.predict(in);

end

MEX コード生成の実行

エントリポイント関数 logonet_predict 用の CUDA コードを生成するには、MEX ターゲットの GPU コード構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数coder.DeepLearningConfigを使用して TensorRT 深層学習構成オブジェクトを作成し、それを GPU コード構成オブジェクトの DeepLearningConfig プロパティに割り当てます。入力サイズを 227×227×3 に指定して codegen コマンドを実行します。この値は、ロゴ認識ネットワークの入力層サイズに対応します。既定では、TensorRT コードを生成すると、32 ビット浮動小数点で推論が実行されます。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('tensorrt');
codegen -config cfg logonet_predict -args {coder.typeof(single(0),[227 227 3])} -report
Code generation successful: View report

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

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

im = imread('gpucoder_tensorrt_test.png');
im = imresize(im, [227,227]);
predict_scores = logonet_predict_mex(single(im));

% get top 5 probability scores and their labels
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
classnames = net.Layers(end).ClassNames;
top5labels = classnames(indx(1:5));

上位 5 つの分類ラベルを表示します。

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

scol = 1;
srow = 20;

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

 imshow(outputImage);

読み込まれた MEX 関数を削除して、GPU メモリを解放します。

clear mex;

8 ビット整数予測用の TensorRT コードの生成

int8 の精度で推論を実行する TensorRT コードを生成します。

8 ビット整数精度の推論計算を備えた NVIDIA TensorRT ライブラリを使用してコード生成を行う場合は、次のネットワークもサポートされます。

  • YOLOv2 や SSD などのオブジェクト検出器ネットワーク

  • 回帰ネットワークおよびセマンティック セグメンテーション ネットワーク

TensorRT で、浮動小数点で学習済みのネットワークのキャリブレーションを行って 8 ビット整数精度で推論を計算するには、キャリブレーション データセットが必要です。データ型を int8 に設定し、キャリブレーション データ セットへのパスを DeepLearningConfig を使用して設定します。logos_dataset は、分類ラベルによりグループ化されたイメージを含むサブフォルダーです。int8 をサポートするには、GPU の Compute Capability が 6.1、7.0、またはそれ以上でなければなりません。

セマンティック セグメンテーション ネットワークでは、キャリブレーション データ イメージが関数 imread でサポートされている形式でなければならないことに注意してください。

unzip('logos_dataset.zip');
cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.GpuConfig.ComputeCapability = '6.1';
cfg.DeepLearningConfig = coder.DeepLearningConfig('tensorrt');
cfg.DeepLearningConfig.DataType = 'int8';
cfg.DeepLearningConfig.DataPath = 'logos_dataset';
cfg.DeepLearningConfig.NumCalibrationBatches = 50;
codegen -config cfg logonet_predict -args {coder.typeof(int8(0),[227 227 3])} -report
Code generation successful: View report

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

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

im = imread('gpucoder_tensorrt_test.png');
im = imresize(im, [227,227]);    
predict_scores = logonet_predict_mex(int8(im));

% get top 5 probability scores and their labels
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
classnames = net.Layers(end).ClassNames;
top5labels = classnames(indx(1:5));

上位 5 つの分類ラベルを表示します。

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

scol = 1;
srow = 20;

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

 imshow(outputImage);

読み込まれた MEX 関数を削除して、GPU メモリを解放します。

clear mex;

16 ビット浮動小数点予測用の TensorRT コードの生成

fp16 の精度で推論を実行する TensorRT コードを生成します。fp16 をサポートするには、GPU の Compute Capability が 5.3、6.0、6.2、またはそれ以上でなければなりません。

単精度での演算を累積したものを半精度に変換した場合、量子化誤差が発生することに注意してください。詳細については、深層ニュートラル ネットワークの量子化を参照してください。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.GpuConfig.ComputeCapability = '5.3';
cfg.DeepLearningConfig = coder.DeepLearningConfig('tensorrt');
cfg.DeepLearningConfig.DataType = 'fp16';
codegen -config cfg logonet_predict -args {coder.typeof(half(0),[227 227 3])} -report
Code generation successful: View report

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

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

im = imread('gpucoder_tensorrt_test.png');

im = imresize(im, [227,227]);    
predict_scores = logonet_predict_mex(half(im));

% get top 5 probability scores and their labels
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
classnames = net.Layers(end).ClassNames;
top5labels = classnames(indx(1:5));

上位 5 つの分類ラベルを表示します。

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

scol = 1;
srow = 20;

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

 imshow(outputImage);

読み込まれた MEX 関数を削除して、GPU メモリを解放します。

clear mex;

参考

関数

オブジェクト

関連するトピック