NVIDIA TensorRT ライブラリを使用した深層学習での予測
この例では、NVIDIA® TensorRT™ ライブラリを使用して深層学習アプリケーションのコードを生成する方法を示します。この例では、codegen
コマンドを使用し、TensorRT を使用してロゴ認識分類ネットワークで予測を実行する MEX ファイルを生成します。この例では、codegen
コマンドを使用して、8 ビット整数および 16 ビット浮動小数点予測を実行する MEX ファイルを生成する方法も示します。
サードパーティの必要条件
必須
この例では、CUDA® MEX を生成します。CUDA 対応 NVIDIA GPU および互換性のあるドライバーが必要です。8 ビット整数および 16 ビット浮動小数点精度モードについては、特定の GPU Compute Capability が必要です。サードパーティ ハードウェア (GPU Coder)を参照してください。
オプション
静的ライブラリ、動的ライブラリ、実行可能ファイルなどの MEX 以外のビルドについては、以下も必要になります。
NVIDIA Toolkit。
NVIDIA cuDNN と TensorRT ライブラリ。
コンパイラおよびライブラリの環境変数。詳細については、サードパーティ ハードウェア (GPU Coder)と前提条件となる製品の設定 (GPU Coder)を参照してください。
GPU 環境の検証
関数coder.checkGpuInstall
(GPU Coder)を使用して、この例を実行するのに必要なコンパイラおよびライブラリが正しく設定されていることを検証します。
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'tensorrt'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
事前学習済みネットワークのダウンロードと読み込み
この例では、事前学習済みのロゴ認識ネットワークを使用して、イメージ内のロゴを分類します。MathWorks の Web サイトから事前学習済みの LogoNet
ネットワークをダウンロードし、ファイルを読み込みます。このネットワークは MATLAB で開発されたもので、サイズは約 42 MB です。このネットワークはさまざまなライティング条件とカメラの角度の下で 32 個のロゴを認識できます。ロゴ認識ネットワークの学習の詳細については、ロゴ認識ネットワーク (GPU Coder)を参照してください。
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
(GPU Coder)を使用して 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 ビット整数精度で推論を計算するには、キャリブレーション データセットが必要です。DeepLearningConfig
を使用して、データ型を int8
に設定し、キャリブレーション データ セットへのパスを設定します。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、またはそれ以上でなければなりません。
単精度での演算を累積してから半精度に変換すると量子化誤差が発生することに注意してください。詳細については、深層ニュートラル ネットワークの量子化 (GPU Coder)を参照してください。
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;