最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

TensorRT を使用した深層学習ネットワークのコード生成

GPU Coder™ を使用して、Deep Learning Toolbox™ からさまざまな事前学習済みの深層学習ネットワークの予測に対する最適化されたコードを生成できます。生成コードでは、アーキテクチャを使用した深層畳み込みニューラル ネットワーク (CNN)、層、および入力オブジェクト (SeriesNetwork または DAGNetwork) で指定したパラメーターが実装されます。NVIDIA® GPU に対する NVIDIA TensorRT™ の高性能な推定ライブラリを利用するようにコード ジェネレーターを構成できます。TensorRT では、ネットワーク層を組み合わせてカーネルの選択を最適化することにより、レイテンシ、スループット、メモリの効率を向上させます。TensorRT の精度モード (FP32、FP16、INT8) を利用し、パフォーマンスをさらに向上させて必要なメモリ量を削減するようにコード ジェネレーターを構成することもできます。生成されたコードは、ソース コード、スタティック ライブラリまたはダイナミック ライブラリ、あるいはさまざまな NVIDIA GPU プラットフォームに配布できる実行可能ファイルをプロジェクトに統合できます。

メモ

TensorRT ワーク フローは MATLAB® オンラインでサポートされていません。

次のいずれかの方法を使用して畳み込みネットワークのコードを生成します。

  • MATLAB エントリポイント関数から CUDA® コードを生成する標準の関数 codegen

  • CUDA コードを生成し、指定したネットワーク オブジェクトのスタティック ライブラリをビルドする cnncodegen コマンド。

  • MATLAB エントリポイント関数から CUDA コードを生成する GPU Coder アプリ。

codegen または GPU Coder アプリを使用してニューラル ネットワークのコードを生成すると、生成コードでは配列データに列優先のレイアウトが使用されます。深層学習ライブラリで使用される行優先のレイアウトと一致させるために、コード ジェネレーターは、列優先レイアウトを行優先レイアウトに変換する操作を挿入しなければなりません。これらの変換操作によって生成コードのパフォーマンスが低下する可能性があります。深層学習ニューラル ネットワークのコード生成では、RowMajor 構成パラメーターなどのコーダーの行優先オプションがサポートされません。

GoogLeNet を使用したコードの生成およびイメージの分類

この例では、GPU Coder を使用して事前学習済みの googlenet 深層畳み込みニューラル ネットワークの CUDA コードを生成し、イメージを分類します。GoogLeNet は、100 万枚を超えるイメージで学習しており、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マグ カップ、鉛筆、動物など) に分類できます。このネットワークは広範囲にわたるイメージについての豊富な特徴表現を学習しています。このネットワークは入力としてイメージを取ってから、イメージ内のオブジェクトのラベルを各オブジェクト カテゴリの確率と共に出力します。この例では、codegen コマンド、cnncodegen コマンド、および GPU Coder アプリを使用して事前学習済みのネットワークのコードを生成する方法を説明します。

この例では、32 ビット浮動小数点 (既定値) をテンソル入力の精度として使用します。テンソルに対する 8 ビット整数精度の使用の詳細については、NVIDIA TensorRT を使用した深層学習での予測の例を参照してください。


要件

  1. Deep Learning Toolbox。

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

  3. GPU Coder Interface for Deep Learning Libraries サポート パッケージ。サポート パッケージをインストールするには、MATLAB の [アドオン] メニューでサポート パッケージを選択します。

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

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

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

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

    net = googlenet;
    

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

    analyzeNetwork(net);
    

  3. 分類するイメージのサイズは、ネットワークの入力サイズと同じでなければなりません。GoogLeNet の場合、imageInputLayer のサイズは 224 x 224 x 3 です。出力 classificationLayerClasses プロパティには、ネットワークによって学習されたクラスの名前が含まれています。合計 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 を呼び出して応答を予測する。

  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 メソッドを使用することもできます。たとえば、次のコードの行は layerIdx で指定された層のネットワーク活性化を返します。activations メソッドの使用上の注意および制限については、サポートされる関数の表の対応するエントリを参照してください。

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

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 以上の CUDA GPU が必要です。FP16 の精度には、Compute Capability 7.0 以上の CUDA GPU が必要です。GpuConfig オブジェクトの ComputeCapability プロパティを使用して、適切な Compute Capability 値に設定します。

  3. codegen コマンドを実行します。codegen コマンドは googlenet_predict.m MATLAB エントリポイント関数から 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 に指示します。

  4. コード生成に成功したら、MATLAB コマンド ウィンドウで [レポートの表示] をクリックすることで、結果のコード生成レポートを表示できます。レポートがレポート ビューアー ウィンドウに表示されます。コード生成時にコード ジェネレーターによりエラーまたは警告が検出されると、レポートでは問題が説明され、問題のある MATLAB コードへのリンクが提供されます。コード生成レポート (MATLAB Coder)を参照してください。

    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 フォルダーに配置します。

メモ

Windows® システムの場合、Bit Defender などのウイルス対策ソフトウェアによって、一部の重みファイルが感染されていると誤って識別され、削除される場合があります。これらのケースは誤検知であり、ウイルス対策プログラムでファイルを安全であるとしてマークできます。

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

 googlenet_predict.cu ファイル

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

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

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

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

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

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

cnncodegen を使用したコード生成

cuDNN ライブラリを使ってコードを生成するには、cnncodegen コマンドの targetlib オプションを使用します。cnncodegen コマンドは、SeriesNetwork または DAGNetwork オブジェクトについて、CUDA コードを生成し、スタティック ライブラリをビルドします。

  1. 事前学習済みのネットワークを読み込みます。詳細については、コード生成用の事前学習済みのネットワークの読み込みを参照してください。

  2. 'tensorrt' として指定された 'targetlib' をもつ cnncodegen を呼び出します。次に例を示します。

    net = googlenet;
    cnncodegen(net,'targetlib','tensorrt');
    

    cnncodegen コマンドはコード、makefile、cnnbuild_rtw.mk を生成し、ライブラリ ファイル cnnbuild をビルドします。これはすべての生成されたファイルを codegen フォルダーに配置します。

生成コード

DAG ネットワークは、144 個の層クラスから成る配列を含む C++ クラス (CnnMain) として生成されます。cnn_exec.hpp ファイルからのクラス宣言のスニペットが表示されます。

 cnn_exec.hpp ファイル

  • このクラスの setup() メソッドは、ハンドルを設定し、ネットワーク オブジェクトの各層にメモリを割り当てます。

  • predict() メソッドは、ネットワーク内の 144 個の層それぞれについて予測を呼び出します。

  • cnn_exec.cpp ファイルには CnnMain クラスのオブジェクト関数の定義が含まれます。

バイナリ ファイルは、ネットワーク内の全結合層や畳み込み層などのパラメーターを持つ層に対してエクスポートされます。たとえば、ファイル cnn_CnnMain_conv*_w および cnn_CnnMain_conv*_b は、ネットワーク内の convolutional 層の重みとバイアス パラメーターに対応します。コード ジェネレーターは、これらのバイナリ ファイルを codegen フォルダーに配置します。コード ジェネレーターはライブラリ ファイル cnnbuild をビルドし、生成されたすべてのファイルを codegen フォルダーに配置します。

生成された 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(I,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')
    

参考

| | |

関連するトピック