このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
TensorRT を使用した深層学習ネットワークのコード生成
GPU Coder™ を使用して、Deep Learning Toolbox™ からさまざまな事前学習済みの深層学習ネットワークの予測に対する最適化されたコードを生成できます。生成コードでは、アーキテクチャを使用した深層畳み込みニューラル ネットワーク (CNN)、層、および入力オブジェクト (SeriesNetwork
(Deep Learning Toolbox) または DAGNetwork
(Deep Learning Toolbox)) で指定したパラメーターが実装されます。NVIDIA® GPU に対する NVIDIA TensorRT™ の高性能な推論ライブラリを利用するようにコード ジェネレーターを構成できます。TensorRT では、ネットワーク層を組み合わせてカーネルの選択を最適化することにより、レイテンシ、スループット、メモリの効率を向上させます。TensorRT の精度モード (FP32、FP16、INT8) を利用し、パフォーマンスをさらに向上させて必要なメモリ量を削減するようにコード ジェネレーターを構成することもできます。生成されたコードは、ソース コード、スタティック ライブラリまたはダイナミック ライブラリ、あるいはさまざまな NVIDIA GPU プラットフォームに展開できる実行可能ファイルとしてプロジェクトに統合できます。
メモ
TensorRT ワーク フローは MATLAB® Online™ でサポートされていません。
次のいずれかの方法を使用して畳み込みネットワークのコードを生成します。
MATLAB エントリポイント関数から CUDA® コードを生成する標準の関数
codegen
。MATLAB エントリポイント関数から CUDA コードを生成する GPU Coder アプリ。
メモ
以前のリリースでは、関数 cnncodegen
を使用することによって TensorRT ライブラリを対象にすることができました。R2021a 以降、関数 cnncodegen
は ARM® Mali GPU プロセッサ専用の C++ コードと makefile を生成します。
GoogLeNet を使用したコードの生成およびイメージの分類
この例では、GPU Coder を使用して事前学習済みの googlenet
(Deep Learning Toolbox) 深層畳み込みニューラル ネットワークの CUDA コードを生成し、イメージを分類します。GoogLeNet は、100 万枚を超えるイメージで学習しており、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マグ カップ、鉛筆、動物など) に分類できます。このネットワークは広範囲にわたるイメージについての豊富な特徴表現を学習しています。このネットワークは入力としてイメージを取ってから、イメージ内のオブジェクトのラベルを各オブジェクト カテゴリの確率と共に出力します。この例では、codegen
コマンドと GPU Coder アプリを使用して事前学習済みのネットワークのコードを生成する方法を示します。
この例では、32 ビット浮動小数点 (既定値) をテンソル入力の精度として使用します。テンソルに対する 8 ビット整数精度の使用の詳細については、NVIDIA TensorRT ライブラリを使用した深層学習予測の例を参照してください。
要件
必須
この例では、以下の追加の要件を持つ CUDA MEX を生成します。
Deep Learning Toolbox.
Deep Learning Toolbox Model for GoogLeNet Network サポート パッケージ。
GPU Coder Interface for Deep Learning Libraries サポート パッケージ。
CUDA 対応 NVIDIA GPU および互換性のあるドライバー。8 ビット整数精度では、Compute Capability 6.1、7.0、またはそれ以上の CUDA GPU が必要です。半精度では、Compute Capability 5.3、6.0、6.2、またはそれ以上の CUDA GPU が必要です。
オプション
スタティック ライブラリ、ダイナミック ライブラリ、実行可能ファイルなどの MEX 以外のビルドでは、以下の要件も適用されます。
CUDA Toolkit、cuDNN ライブラリ、および TensorRT ライブラリ。サポートされているコンパイラおよびライブラリのバージョンの詳細は、前提条件となる製品のインストールを参照してください。
コンパイラおよびライブラリの環境変数。詳細については、環境変数を参照してください。
事前学習済みのネットワークの読み込み
事前学習済みの GoogLeNet ネットワークを読み込みます。イメージ分類用の異なる事前学習済みネットワークの読み込みを選択できます。必要なサポート パッケージがインストールされていない場合、ダウンロード用リンクが表示されます。
net = googlenet;
オブジェクト
net
にはDAGNetwork
オブジェクトが格納されています。関数analyzeNetwork
(Deep Learning Toolbox) を使用して、ネットワーク アーキテクチャを対話的に可視化して表示し、ネットワークに関するエラーや問題を検出して、ネットワーク層についての詳細情報を表示します。層の情報には、層の活性化と学習可能なパラメーターのサイズ、学習可能なパラメーターの総数、および再帰層の状態パラメーターのサイズが含まれます。analyzeNetwork(net);
分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。GoogLeNet の場合、
imageInputLayer
(Deep Learning Toolbox) のサイズは 224 x 224 x 3 です。出力classificationLayer
(Deep Learning Toolbox) のClasses
プロパティには、ネットワークによって学習されたクラスの名前が含まれています。合計 1000 個のクラス名のうち 10 個をランダムに表示します。classNames = net.Layers(end).Classes; numClasses = numel(classNames); disp(classNames(randperm(numClasses,10)))
'speedboat' 'window screen' 'isopod' 'wooden spoon' 'lipstick' 'drake' 'hyena' 'dumbbell' 'strawberry' 'custard apple'
詳細については、深層学習層の一覧 (Deep Learning Toolbox)を参照してください。
エントリポイント関数の作成
MATLAB で次を行うエントリポイント関数を記述します。
関数
coder.loadDeepLearningNetwork
を使用して深層学習モデルを読み込み、CNN クラスを作成して設定する。詳細については、コード生成用の事前学習済みのネットワークの読み込みを参照してください。predict
(Deep Learning Toolbox) を呼び出して応答を予測する。
次に例を示します。
function out = googlenet_predict(in) %#codegen persistent mynet; if isempty(mynet) mynet = coder.loadDeepLearningNetwork('googlenet'); end % pass in input out = predict(mynet,in);
永続オブジェクト
mynet
はDAGNetwork
オブジェクトを読み込みます。エントリポイント関数への最初の呼び出しで、永続オブジェクトが作成されて設定されます。後続の関数の呼び出しでは、入力の呼び出しpredict
に同じオブジェクトが再利用され、ネットワーク オブジェクトの再構成と再読み込みが回避されます。メモ
コード生成では、ネットワークを永続オブジェクトに読み込む必要があります。
特定の層のネットワーク活性化に
activations
(Deep Learning Toolbox) メソッドを使用することもできます。たとえば、次のコードの行はlayerIdx
で指定された層のネットワーク活性化を返します。out = activations(mynet,in,layerIdx,'OutputAs','Channels');
classify
(Deep Learning Toolbox) メソッドを使用して、学習済みネットワークmynet
でin
のイメージ データのクラス ラベルを予測することもできます。[out,scores] = classify(mynet,in);
LSTM ネットワークに対しては、
predictAndUpdateState
(Deep Learning Toolbox) メソッドとresetState
(Deep Learning Toolbox) メソッドも使用できます。これらのメソッドの使用上の注意および制限については、サポートされる関数の表の対応するエントリを参照してください。
codegen
を使用したコード生成
出力ファイル名、場所、タイプなどのビルド設定を構成するには、コーダー構成オブジェクトを作成します。このオブジェクトを作成するには、関数
coder.gpuConfig
を使用します。たとえば、codegen
コマンドを使用して CUDA MEX を生成する場合、cfg = coder.gpuConfig('mex');
を使用します。その他の利用可能なオプションは次のとおりです。
cfg = coder.gpuConfig('lib');
、CUDA C/C++ スタティック ライブラリの生成時にcodegen
で使用するコード生成構成オブジェクトを作成します。cfg = coder.gpuConfig('dll');
、CUDA C/C++ ダイナミック ライブラリの生成時にcodegen
で使用するコード生成構成オブジェクトを作成します。cfg = coder.gpuConfig('exe');
、CUDA C/C++ 実行可能ファイルの生成時にcodegen
で使用するコード生成構成オブジェクトを作成します。
TensorRT のコード生成パラメーターを指定するには、
DeepLearningConfig
プロパティを、coder.DeepLearningConfig
を使用して作成したcoder.TensorRTConfig
オブジェクトに設定します。cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('tensorrt'); cfg.DeepLearningConfig.DataType = 'fp32';
DataType
プロパティを使用することによって、サポートされている層での推論計算の精度を指定します。32 ビット浮動小数点の推論を実行する場合、'fp32'
を使用します。半精度には、'fp16'
を使用します。8 ビット整数には、'int8'
を使用します。既定値は'fp32'
です。INT8
の精度には、Compute Capability 6.1、7.0、またはそれ以上の CUDA GPU が必要です。FP16
の精度には、Compute Capability 5.3、6.0、6.2、またはそれ以上の CUDA GPU が必要です。GpuConfig
オブジェクトのComputeCapability
プロパティを使用して、適切な Compute Capability 値に設定します。'INT8'
オプションを選択すると、TensorRT は浮動小数点データをint8
に量子化します。キャリブレーションは、絞り込んだキャリブレーション データのセットを使用して実行されます。キャリブレーション データは、DataPath
で指定したイメージ データの位置に存在していなければなりません。キャリブレーションの前にイメージの前処理を実行し、コード生成の前に前処理ステップをエントリポイント ファイルに含めなければなりません。8 ビット整数精度の推論計算を備えた NVIDIA TensorRT ライブラリを使用してコード生成を行う場合は、次のネットワークもサポートされます。
YOLOv2 や SSD などのオブジェクト検出器ネットワーク。
回帰ネットワークおよびセマンティック セグメンテーション ネットワーク。セマンティック セグメンテーション ネットワークでは、再キャリブレーション イメージが関数
imread
でサポートされている形式でなければなりません。
TensorRT を使用したロゴ分類ネットワークに対して 8 ビット整数で予測を実行する例については、NVIDIA TensorRT ライブラリを使用した深層学習予測を参照してください。
codegen
コマンドを実行します。codegen
コマンドは MATLAB エントリポイント関数googlenet_predict.m
から CUDA コードを生成します。codegen -config cfg googlenet_predict -args {ones(224,224,3)} -report
-report
オプションは、MATLAB コードのデバッグに使用できるコード生成レポートを生成するようにcodegen
に指示します。-args
オプションは、入力 in で指定したクラス、サイズ、および実数/複素数を使用して、ファイルgooglenet_predict.m
をコンパイルするようにcodegen
に指示します。値(224,224,3)
は GoogLeNet ネットワークの入力層サイズに対応します。-config
オプションは、指定した構成オブジェクトをコード生成に使用するようにcodegen
に指示します。
メモ
コード生成に半精度の入力を指定できます。ただし、コード ジェネレーターの型は入力を単精度にキャストします。Deep Learning Toolbox は、MATLAB 内のすべての計算に単精度浮動小数点演算を使用します。コード生成時、
coder.TensorRTConfig
のDataType
プロパティに'fp16'
を指定することで、半精度 (16 ビット浮動小数点) の入力での推論を有効にできます。コード ジェネレーターは、既定で列優先のレイアウトを使用します。行優先のレイアウトを使用するには、
codegen
コマンドに-rowmajor
オプションを渡します。あるいは、コード生成構成オブジェクトのcfg.RowMajor
パラメーターを変更して、行優先のレイアウトでコードを構成します。コード生成に成功したら、MATLAB コマンド ウィンドウで [レポートの表示] をクリックすることで、結果のコード生成レポートを表示できます。レポートがレポート ビューアー ウィンドウに表示されます。コード生成時にコード ジェネレーターによりエラーまたは警告が検出されると、レポートでは問題が説明され、問題のある MATLAB コードへのリンクが提供されます。コード生成レポートを参照してください。
Code generation successful: View report
生成コード
DAG ネットワークは、144 個の層クラスから成る配列を含む C++ クラスとして生成されます。googlenet_predict_types.h
ファイルからのクラス宣言のスニペットが表示されます。
googlenet_predict_types.h
ファイル
このクラスの
setup()
メソッドは、ハンドルを設定し、ネットワーク オブジェクトの各層にメモリを割り当てます。predict()
メソッドは、ネットワーク内の 144 個の層それぞれについて予測を呼び出します。DeepLearningNetwork.cu
ファイルにはb_googlenet_0
クラスのオブジェクト関数の定義が含まれます。
バイナリ ファイルは、ネットワーク内の全結合層や畳み込み層などのパラメーターを持つ層に対してエクスポートされます。たとえば、ファイル cnn_googlenet_conv*_w
および cnn_googlenet_conv*_b
は、ネットワーク内の convolutional
層の重みとバイアス パラメーターに対応します。コード ジェネレーターは、これらのバイナリ ファイルを codegen
フォルダーに配置します。
既定では、生成されたアプリケーションは codegen
フォルダー内の重みファイルを検索します。生成されたアプリケーションと重みファイルを組み込みボードなどの別の場所に再配置する場合は、USER_DL_DATA_PATH
という環境変数を作成します。この値は、再配置された重みファイルの場所です。生成されたアプリケーションは、この場所で重みファイルを探します。
メモ
Windows® システムの場合、Bit Defender などのウイルス対策ソフトウェアによって、一部の重みファイルが感染されていると誤って識別され、削除される場合があります。これらのケースは誤検知であり、ウイルス対策プログラムでファイルを安全であるとしてマークできます。
生成されたコード ファイル googlenet_predict()
で、エントリポイント関数 googlenet_predict.cu
は、b_googlenet_0 クラス型の静的オブジェクトを構築し、このネットワーク オブジェクトに対して setup や predict を呼び出します。
アプリを使用したコード生成
エントリポイント関数を指定し、入力の型を指定するには、アプリで手順を完了します。GPU Coder アプリを使用したコード生成を参照してください。
[コード生成] 手順で、以下を行います。
[ビルド タイプ]
をMEX
に設定します。[詳細設定] をクリックします。[深層学習] ペインで、[ターゲット ライブラリ] を [TensorRT] に設定します。
設定ウィンドウを閉じます。CUDA コードを生成するには、[生成] をクリックします。
生成された makefile
'lib'
、'dll'
、および 'exe'
ターゲットに対して、コード ジェネレーターは codegen
フォルダーに *_rtw.mk
make ファイルを作成します。この make ファイルでは、生成されたコードの場所は MACROS
セクションで検出された変数 START_DIR
を使用して指定されます。既定では、この変数は、コードが生成される現在の作業フォルダーのパスを指します。生成されたファイルを移動し、makefile を使用してビルドする予定がある場合は、START_DIR
の生成された値を適切なパスの場所で置き換えます。
生成された MEX の実行
分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。分類するイメージを読み取り、そのサイズをネットワークの入力サイズに変更します。このサイズ変更では、イメージの縦横比が多少変化します。
im = imread("peppers.png"); inputLayerSize = net.Layers(1).InputSize; im = imresize(im,inputLayerSize(1:2));
入力イメージに対して GoogLeNet の predict を呼び出します。
predict_scores = googlenet_predict_mex(im);
上位 5 つの予測ラベルとそれらに対応する確率をヒストグラムとして表示します。ネットワークはイメージを非常に多くのオブジェクト カテゴリに分類しますが、多くのカテゴリは似ているため、ネットワークを評価するときは、通常、上位 5 つの精度を考慮します。このネットワークは高い確率でこのイメージをピーマンとして分類します。
[scores,indx] = sort(predict_scores, 'descend'); 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 5 predictions using GoogLeNet')