このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
YOLO v3 深層学習を使用したオブジェクト検出用のコード生成
この例では、You Only Look Once (YOLO) v3 オブジェクト検出器用の CUDA® MEX を生成する方法を示します。YOLO v3 は YOLO v2 を改良したもので、複数のスケールにおける検出を追加してより小さなオブジェクトを検出できるようになっています。さらに、学習で使用される損失関数は、境界ボックス回帰用の平均二乗誤差と、オブジェクト分類用のバイナリ交差エントロピーに分割されており、検出精度が向上しています。この例で使用する YOLO v3 ネットワークは、Computer Vision Toolbox (TM) の "YOLO v3 深層学習を使用したオブジェクトの検出" の例を使用して学習させたものです。詳細は、YOLO v3 深層学習を使用したオブジェクトの検出 (Computer Vision Toolbox) を参照してください。
サードパーティの必要条件
必須
CUDA 対応 NVIDIA® GPU および互換性のあるドライバー。
オプション
スタティック ライブラリ、ダイナミック ライブラリ、または実行可能ファイルなどの MEX 以外のビルドについて、この例では以下の要件も適用されます。
NVIDIA CUDA ツールキット。
NVIDIA cuDNN ライブラリ。
コンパイラおよびライブラリの環境変数。詳細は、サードパーティ ハードウェア (GPU Coder)と前提条件となる製品の設定 (GPU Coder)を参照してください。
GPU 環境の検証
この例を実行するためのコンパイラおよびライブラリが正しく設定されていることを確認するために、関数coder.checkGpuInstall
(GPU Coder)を使用します。
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
YOLO v3 ネットワーク
この例の YOLO v3 ネットワークは、squeezenet
がベースとなっています。このネットワークは、SqueezeNet の特徴抽出ネットワークを使用し、最後に 2 つの検出ヘッドが追加されています。2 番目の検出ヘッドのサイズは、最初の検出ヘッドの 2 倍となっているため、小さなオブジェクトをより的確に検出できます。検出するオブジェクトのサイズに基づいて、さまざまなサイズの検出ヘッドを任意の数で指定できます。YOLO v3 ネットワークは、学習データを使用して推定されたアンカー ボックスを使用します。これにより、データセットの種類に対応した初期の事前確率が改善され、ボックスを正確に予測できるようにネットワークに学習させることができます。アンカー ボックスの詳細については、アンカー ボックスによるオブジェクトの検出 (Computer Vision Toolbox)を参照してください。
この例の YOLO v3 ネットワークを次の図に示します。
各検出ヘッドは、境界ボックス座標 (x、y、幅、高さ)、オブジェクトの信頼度、および各アンカー ボックス マスクに対するクラスの確率を予測します。そのため、各検出ヘッドにおける最終畳み込み層の出力フィルターの数は、アンカー ボックス マスクの数と、アンカー ボックスあたりの予測要素の数を乗算したものになります。この検出ヘッドは、ネットワークの出力層を構成します。
事前学習済みの YOLO v3 ネットワーク
この例では、事前学習済みの YOLO v3 ネットワークを含む yolov3SqueezeNetVehicleExample_21aSPKG.zip
ファイルを使用します。ファイルのサイズは約 23 MB です。MathWorks の Web サイトからファイルをダウンロードし、ファイルを解凍します。
fileName = matlab.internal.examples.downloadSupportFile('vision/data/','yolov3SqueezeNetVehicleExample_21aSPKG.zip'); data = unzip(fileName); matFile = data{1,1}; vehicleDetector = load(matFile); net = vehicleDetector.detector.Network
net = dlnetwork with properties: Layers: [75×1 nnet.cnn.layer.Layer] Connections: [84×2 table] Learnables: [66×3 table] State: [6×3 table] InputNames: {'data'} OutputNames: {'customOutputConv1' 'customOutputConv2'} Initialized: 1
メモ: 事前学習済みの検出器ネットワークは、Computer Vision Toolbox™ Model for YOLO v3 Object Detection サポート パッケージからも利用できます。
この事前学習済みネットワークを使用するには、最初にアドオン エクスプローラーから Computer Vision Toolbox Model for YOLO v3 Object Detection をインストールしなければなりません。アドオンのインストールの詳細については、アドオンの取得と管理を参照してください。
次に、yolov3ObjectDetector
オブジェクトを MAT ファイルに保存して続行します。次に例を示します。
detector = yolov3ObjectDetector('darknet53-coco'); matFile = 'pretrainedYOLOv3Detector.mat'; save(matFile,'detector');
エントリポイント関数 yolov3Detect
エントリポイント関数 yolov3Detect
は、イメージ入力を受け取り、yolov3SqueezeNetVehicleExample_21aSPKG.mat
ファイルに保存されている深層学習ネットワークを使用して、イメージに対して検出器を実行します。この関数は、ネットワーク オブジェクトを yolov3SqueezeNetVehicleExample_21aSPKG.mat
ファイルから永続変数 yolov3Obj に読み込み、それ以降の検出の呼び出しではこの永続オブジェクトを再利用します。
type('yolov3Detect.m')
function outImg = yolov3Detect(in,matFile) % Copyright 2021 The MathWorks, Inc. persistent yolov3Obj; if isempty(yolov3Obj) yolov3Obj = coder.loadDeepLearningNetwork(matFile); end % Call to detect method [bboxes,~,labels] = yolov3Obj.detect(in,'Threshold',0.5); % Convert categorical labels to cell array of charactor vectors labels = cellstr(labels); % Annotate detections in the image. outImg = insertObjectAnnotation(in,'rectangle',bboxes,labels);
CUDA MEX の生成
エントリポイント関数用の CUDA コードを生成するには、MEX ターゲットの GPU コード構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数 coder.DeepLearningConfig
(GPU Coder) を使用して CuDNN
深層学習構成オブジェクトを作成し、それを GPU コード構成オブジェクトの DeepLearningConfig
プロパティに割り当てます。入力サイズ 227×227×3 を指定して codegen
コマンドを実行します。この値は YOLOv3 の入力層サイズに対応します。
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); cfg.GenerateReport = true; inputArgs = {ones(227,227,3,'uint8'),coder.Constant(matFile)}; codegen -config cfg yolov3Detect -args inputArgs -report
Code generation successful: View report
TensorRT ターゲット用の CUDA® コードを生成するには、CuDNN 構成オブジェクトではなく、TensorRT 深層学習構成オブジェクトを使用します。同様に、MKLDNN ターゲット用のコードを生成するには、CPU コード構成オブジェクトを作成し、その DeepLearningConfig
プロパティとして MKLDNN 深層学習構成オブジェクトを使用します。
生成された MEX の実行
ビデオ ファイル リーダーを設定し、入力ビデオを読み取ります。ビデオ プレイヤーを作成し、ビデオと出力の検出を表示します。
videoFile = 'highway_lanechange.mp4'; videoFreader = vision.VideoFileReader(videoFile,'VideoOutputDataType','uint8'); depVideoPlayer = vision.DeployableVideoPlayer('Size','Custom','CustomSize',[640 480]);
ビデオ入力をフレームごとに読み取り、検出器を使用してビデオ内の車両を検出します。
cont = ~isDone(videoFreader); while cont I = step(videoFreader); in = imresize(I,[227,227]); out = yolov3Detect_mex(in,matFile); step(depVideoPlayer, out); % Exit the loop if the video player figure window is closed cont = ~isDone(videoFreader) && isOpen(depVideoPlayer); end
参考文献
1.Redmon, Joseph, and Ali Farhadi. "YOLOv3: An Incremental Improvement." Preprint, submitted April 8, 2018. https://arxiv.org/abs/1804.02767.