【jetson】deepstream-appでYoloを動かしてみる

スポンサーリンク
【jetson】deepstream-appでYoloを動かしてみるAIを作ってみる
この記事を読んで分かること
  • deepstream-appでYoloモデルを動かす方法

 

deepstream-appのプログラム

今回は、deepstream-appのサンプルプログラムである「source1_usb_dec_infer_resnet_int8.txt」を使ってYoloモデルを動かします。

source1_usb_dec_infer_resnet_int8の構成

primmary-gieのコンフィグを書き換えてYoloモデルを読み込むようにしていきます。

準備が必要なファイルは以下の3種類です。

Yolo動作に必要なファイル
  • モデルファイル(yolo.cfg,  yolo.weights)
  • ラベルファイル(labels.txt)
  • Yoloカスタムライブラリ(libnvdsinfer_custom_impl_Yolo.so)

 

source1_usb_dec_infer_resnet_int8.txt」の挙動についてはこちらの記事で解説しています。

【jetson】deepstream-appのサンプルプログラムを動かしてみた #1
この記事を読んで分かること deepstreamのサンプルプログラムの動かし方 source1_usb_dec_infer_resnet_int8.txtの内容 deepstream-appのコンフィグの意味 ...

 

Yoloモデルの準備

Yoloモデルは学習済みのものをダウンロードして使用していきます。

YoloモデルをダウンロードするプログラムはDeepStreamに同梱されているので、そちらを使用します。

 

cd /opt/nvidia/deepstream/deepstream-5.1/sources/objectDetector_Yolo/
bash prebuild.sh

 

プログラムを実行すると複数のYoloモデルがダウンロードされます。

ダウンロードされるYoloモデル
  • yolov2-tiny
  • yolov2
  • yolov3-tiny
  • yolov3

それぞれコンフィグ(.cfg)重み(.weight)ファイルがあります。

 

ラベルファイルの準備

今回使用するYoloモデルに対応したラベルファイルはDeepStreamに予め用意されています。

以下のパスに格納されているラベルファイルをそのまま使うことができます。

/opt/nvidia/deepstream/deepstream-5.1/sources/objectDetector_Yolo/labels.txt

 

中身は検出対象のラベルが記載されていて、このモデルでは80種類となっています。

labels.txt
person
bicycle
car
motorbike
aeroplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
sofa
pottedplant
bed
diningtable
toilet
tvmonitor
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

 

Yoloカスタムライブラリの準備

DeepStreamの標準ライブラリではYoloモデルを読み込むことができません

そのため、Yoloモデルを読み込むためのカスタムライブラリを作成する必要があります。

作成と言っても、もともと用意されたC++プログラムがあるので、それをビルドするだけです。

 

ビルドにはCUDAのバージョンを環境変数に設定する必要があるので調べていきます。

/usr/local/cuda/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Wed_Oct_23_21:14:42_PDT_2019
Cuda compilation tools, release 10.2, V10.2.89

 

バージョンが10.2であることが確認できたので、環境変数に設定します。

export CUDA_VER=10.2

 

環境変数の準備ができたのでビルドしていきます

cd /opt/nvidia/deepstream/deepstream-5.1/sources/objectDetector_Yolo/
bash prebuild.sh

 

ビルドに成功していれば、nvdsinfer_custom_impl_Yoloディレクトリの中に「libnvdsinfer_custom_impl_Yolo.so」ファイルが作成されます。

 

deepstream-appの設定ファイル変更

サンプルプログラムを元にYolo用に設定を変更していきます。

サンプルプログラムの設定ファイルは2種類あるので、それぞれ見ていきましょう。

設定ファイル
  • source1_usb_dec_infer_resnet_int8.txt
  • config_infer_primary.txt

 

source1_usb_dec_infer_resnet_int8.txt

パイプライン処理全体の設定です。

このファイルでの変更点は2点です。

source1_usb_dec_infer_resnet_int8.txt(変更点のみ)
[primary-gie]
#model-engine-file=./models/Primary_Detector/resnet10.caffemodel_b30_gpu0_int8.engine

[tracker]
enable=1
tracker-width=640
tracker-height=384
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_mot_klt.so

 

model-engine-fileをコメントアウトしました。

モデルの読み込みはこの後出てくる「config_infer_primary.txt」で行うので問題ありません。

 

trackerの設定も追加しました。

前のフレームの検出情報を利用するために設定しています。

 

config_infer_primary.txt

検出モデルの設定です。

変えた部分は大きく3つです。

細かい変更もあるので設定ファイルの内容全てを載せておきます。

config_infer_primary.txt
[property]
gpu-id=0
net-scale-factor=0.0039215697906911373
custom-network-config=yolov3-tiny.cfg
model-file=yolov3-tiny.weights
labelfile-path=labels.txt
process-mode=1
model-color-format=0
## 0=FP32, 1=INT8, 2=FP16 mode
network-mode=0
num-detected-classes=80
interval=0
gie-unique-id=1
output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid
force-implicit-batch-dim=1

## 0=Group Rectangles, 1=DBSCAN, 2=NMS, 3= DBSCAN+NMS Hybrid, 4 = None(No clustering)
cluster-mode=2
maintain-aspect-ratio=1
parse-bbox-func-name=NvDsInferParseCustomYoloV3Tiny
custom-lib-path=nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so
engine-create-func-name=NvDsInferYoloCudaEngineGet

[class-attrs-all]
nms-iou-threshold=0.3
threshold=0.7

 

読み込むモデルをyoloに変更しています。

custom-network-config=yolov3-tiny.cfg
model-file=yolov3-tiny.weights

 

ラベルの情報を変更します。

labelfile-path=labels.txt
num-detected-classes=80

 

モデルの動作情報を変更します。

8ビットではなく32ビットのモデルなので、それに合わせてモードを変更します。

network-mode=0

 

ファイルの配置

ここまでで必要なファイルは揃いました。

ディレクトリ構成は以下のようになっています。

├ objectDetector_Yolo/ 
   ├ source1_usb_dec_infer_resnet_int8.txt/ # deepstream-appの設定ファイル
   ├ config_infer_primary.txt # deepstream-appの推論設定ファイル
   ├ yolov3-tiny.cfg # Yoloのモデルファイル
   ├ yolov3-tiny.weights # Yoloのモデルファイル
   ├ labels.txt # Yoloのクラス定義ファイル
   ├ nvdsinfer_custom_impl_Yolo/ 
   │  ├ libnvdsinfer_custom_impl_Yolo.so # Yoloカスタムライブラリ

 

アプリの実行

deepstream-appを動かしていきます。

deepstream-app -c source1_usb_dec_infer_resnet_int8.txt

 

deepstream-appでYolo

カメラでPCのディスプレイを映して検出している様子です。

しっかりPerson、laptop、chairが検出できていて、無事Yoloのモデルを動かすことができました

 

まとめ

今回は、deepstream-appでYoloモデルを動かしてみました。

サンプルプログラムであるsource1_usb_dec_infer_resnet_int8.txt」を元にカメラの入力を解析しています。

Yoloを動かすために学習済みモデルのダウンロードライブラリの作成も行いました。

高速で動作するYoloモデルをエッジデバイスで体験してみてください。

コメント

  1. ko より:

    はじめまして。こんにちは。
    詳しい解説わかりやすく参考にさせていただきました^^

    もし知見あれば教えていただきたいのですが
    yolov3モデル(yolov3.cfg)を利用した場合、実行時にmaskとfilterの設定?が一致していないのか、下記のようなエラーになってしまっています。
    ~~~
    ERROR: yoloV3 output layer.size: 3 does not match mask.size: 2
    0:01:34.736978273 139 0x5627810c2800 ERROR nvinfer gstnvinfer.cpp:640:gst_nvinfer_logger: NvDsInferContext[UID 1]: Error in NvDsInferContextImp
    ~~~
    よろしくお願いいたします。

  2. ko より:

    補足です。
    当ページでご紹介いただいているyolov3-tiny.cfgモデルを使った方法は、うまくいっておりほぼそのままの設定を引き継いで、モデルの設定箇所のみ、yolov3.cfgモデルを使うように変更しています。

    ~~~ config_infer_primary.txt ~~~
    custom-network-config=yolov3-tiny.cfg
    model-file=yolov3-tiny.weights
    ~~~

    それ以外も設定の変更や、Yoloモデル読み込みのためのカスタムライブラリに手を入れる必要があったりするのでしょうか?
    yolov3.cfgモデルにこだわっているの、yolov3.cfgモデルと同様にカスタムモデルを作成したものがありそれを使うと今回のエラーが発生しているため、yolov3.cfgを使えるようにしたいと思っています。

    お手数ですが、知見がございましたら教えていただけると幸いです。
    よろしくお願いいたします。

  3. ko より:

    自己解決しました。
    モデルを定義しているconfig_infer_primary.txtファイルのYoloカスタムライブラリについて定義している箇所で、Yolov3Tinyの指定からYolov3に変更が必要でした。。。

    ~~~ config_infer_primary.txt ~~~
    parse-bbox-func-name=NvDsInferParseCustomYoloV3Tiny
    ~~~

    ~~~ config_infer_primary.txt ~~~
    parse-bbox-func-name=NvDsInferParseCustomYoloV3
    ~~~

    • シャイニングシャイニング より:

      コメントありがとうございます。
      情報のご提供ありがとうございます。他の方にも有益な情報になるかと思います。
      お役に立てませんでしたが、自己解決できてよかったです。

タイトルとURLをコピーしました