Main Content

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

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 を生成します。

  1. Deep Learning Toolbox.

  2. Deep Learning Toolbox Model for GoogLeNet Network サポート パッケージ。

  3. GPU Coder Interface for Deep Learning サポート パッケージ。

  4. CUDA 対応 NVIDIA GPU および互換性のあるドライバー。8 ビット整数精度では、Compute Capability 6.1、7.0、またはそれ以上の CUDA GPU が必要です。半精度では、Compute Capability 5.3、6.0、6.2、またはそれ以上の CUDA GPU が必要です。

オプション

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

  1. CUDA Toolkit、cuDNN ライブラリ、および TensorRT ライブラリ。サポートされているコンパイラおよびライブラリのバージョンの詳細については、前提条件となる製品のインストールを参照してください。

  2. コンパイラおよびライブラリの環境変数。詳細については、環境変数を参照してください。

事前学習済みのネットワークの読み込み

  1. 事前学習済みの GoogLeNet ネットワークを読み込みます。イメージ分類用の異なる事前学習済みネットワークの読み込みを選択できます。必要なサポート パッケージがインストールされていない場合、ダウンロード用リンクが表示されます。

    net = googlenet;
    

  2. オブジェクト net には DAGNetwork オブジェクトが格納されています。関数 analyzeNetwork (Deep Learning Toolbox) を使用して、ネットワーク アーキテクチャを対話的に可視化して表示し、ネットワークに関するエラーや問題を検出して、ネットワーク層についての詳細情報を表示します。層の情報には、層の活性化と学習可能なパラメーターのサイズ、学習可能なパラメーターの総数、および再帰層の状態パラメーターのサイズが含まれます。

    analyzeNetwork(net);
    

  3. 分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。GoogLeNet の場合、imageInputLayer (Deep Learning Toolbox) のサイズは 224 x 224 x 3 です。出力 ClassificationOutputLayer (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)を参照してください。

エントリポイント関数の作成

  1. MATLAB で次を行うエントリポイント関数を記述します。

    1. 関数 coder.loadDeepLearningNetwork を使用して深層学習モデルを読み込み、CNN クラスを作成して設定する。詳細については、コード生成用の事前学習済みのネットワークの読み込みを参照してください。

    2. predict (Deep Learning Toolbox) を呼び出して応答を予測する。

  2. 次に例を示します。

    function out = googlenet_predict(in) %#codegen
    
    persistent mynet;
    
    if isempty(mynet)
        mynet = coder.loadDeepLearningNetwork('googlenet');
    end
    
    % pass in input   
    out = predict(mynet,in); 
    

    永続オブジェクト mynetDAGNetwork オブジェクトを読み込みます。エントリポイント関数への最初の呼び出しで、永続オブジェクトが作成されて設定されます。後続の関数の呼び出しでは、入力の呼び出し predict に同じオブジェクトが再利用され、ネットワーク オブジェクトの再構成と再読み込みが回避されます。

    メモ

    コード生成では、ネットワークを永続オブジェクトに読み込む必要があります。

  3. 特定の層のネットワーク活性化に activations (Deep Learning Toolbox) メソッドを使用することもできます。たとえば、次のコードの行は layerIdx で指定された層のネットワーク活性化を返します。

    out = activations(mynet,in,layerIdx,'OutputAs','Channels');
    

  4. classify (Deep Learning Toolbox) メソッドを使用して、学習済みネットワーク mynetin のイメージ データのクラス ラベルを予測することもできます。

    [out,scores] = classify(mynet,in);
    

    LSTM ネットワークに対しては、predictAndUpdateState (Deep Learning Toolbox) メソッドと resetState (Deep Learning Toolbox) メソッドも使用できます。これらのメソッドの使用上の注意および制限については、サポートされる関数の表の対応するエントリを参照してください。

codegen を使用したコード生成

  1. 出力ファイル名、場所、タイプなどのビルド設定を構成するには、コーダー構成オブジェクトを作成します。このオブジェクトを作成するには、関数 coder.gpuConfig を使用します。たとえば、codegen コマンドを使用して CUDA MEX を生成する場合、cfg = coder.gpuConfig('mex'); を使用します。

    その他の利用可能なオプションは次のとおりです。

    1. cfg = coder.gpuConfig('lib');、CUDA C/C++ スタティック ライブラリの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

    2. cfg = coder.gpuConfig('dll');、CUDA C/C++ ダイナミック ライブラリの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

    3. cfg = coder.gpuConfig('exe');、CUDA C/C++ 実行可能ファイルの生成時に codegen で使用するコード生成構成オブジェクトを作成します。

  2. 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 ライブラリを使用した深層学習予測を参照してください。

  3. codegen コマンドを実行します。codegen コマンドは MATLAB エントリポイント関数 googlenet_predict.m から CUDA コードを生成します。

    codegen -config cfg googlenet_predict -args {ones(224,224,3)} -report
    

    1. -report オプションは、MATLAB コードのデバッグに使用できるコード生成レポートを生成するように codegen に指示します。

    2. -args オプションは、入力 in で指定したクラス、サイズ、および実数/複素数を使用して、ファイル googlenet_predict.m をコンパイルするように codegen に指示します。値 (224,224,3) は GoogLeNet ネットワークの入力層サイズに対応します。

    3. -config オプションは、指定した構成オブジェクトをコード生成に使用するように codegen に指示します。

    メモ

    コード生成に半精度の入力を指定できます。ただし、コード ジェネレーターの型は入力を単精度にキャストします。Deep Learning Toolbox は、MATLAB での計算に単精度浮動小数点演算を使用します。コード生成時、coder.TensorRTConfigDataType プロパティに 'fp16' を指定することで、半精度 (16 ビット浮動小数点) の入力での推論を有効にできます。

    コード ジェネレーターは、既定で列優先のレイアウトを使用します。行優先のレイアウトを使用するには、codegen コマンドに -rowmajor オプションを渡します。あるいは、コード生成構成オブジェクトの cfg.RowMajor パラメーターを変更して、行優先のレイアウトでコードを構成します。

  4. コード生成に成功したら、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 を呼び出します。

 googlenet_predict.cu ファイル

アプリを使用したコード生成

エントリポイント関数を指定し、入力の型を指定するには、アプリで手順を完了します。GPU Coder アプリを使用したコード生成を参照してください。

[コード生成] 手順で、以下を行います。

  1. [ビルド タイプ]MEX に設定します。

  2. [詳細設定] をクリックします。[深層学習] ペインで、[ターゲット ライブラリ][TensorRT] に設定します。

  3. 設定ウィンドウを閉じます。CUDA コードを生成するには、[生成] をクリックします。

生成された makefile

'lib''dll'、および 'exe' ターゲットに対して、コード ジェネレーターは codegen フォルダーに *_rtw.mk make ファイルを作成します。この make ファイルでは、生成されたコードの場所は MACROS セクションで検出された変数 START_DIR を使用して指定されます。既定では、この変数は、コードが生成される現在の作業フォルダーのパスを指します。生成されたファイルを移動し、makefile を使用してビルドする予定がある場合は、START_DIR の生成された値を適切なパスの場所で置き換えます。

生成された MEX の実行

  1. 分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。分類するイメージを読み取り、そのサイズをネットワークの入力サイズに変更します。このサイズ変更では、イメージの縦横比が多少変化します。

    im = imread("peppers.png");
    inputLayerSize = net.Layers(1).InputSize;
    im = imresize(im,inputLayerSize(1:2));
    
  2. 入力イメージに対して GoogLeNet の predict を呼び出します。

    predict_scores = googlenet_predict_mex(im);
    
  3. 上位 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')
    

参考

関数

オブジェクト

関連するトピック