Posted at

TensorFlow Object Detection APIを使ってFaster R-CNN、R-FCN、SSDを比較してみた


5行まとめ


  • TensorFlow Object Detection APIには各種モデルが準備されており、簡単に試すことができた。

  • SSDは推論がとても早いが学習に時間がかかる。

  • R-FCNは推論時間でSSDに劣るが、検出精度がSSDより高め。学習時間と精度のバランスも良い。

  • ラベル付けの補助としてR-FCNを使い、推論時間が重要な場面での最終的な検出器としてSSDを使うのが良さそう。

  • ラベル付け(アノテーション)は苦行。


概要

 TensorFlow Object Detection APIを使い、独自のデータセットで物体検出(Object Detection)を行ってみました。

使用したモデルは、Faster R-CNN、R-FCN、SSDの3つです。本記事では同一のデータセットに対して3つのモデルを適用し、その精度、速度などを比較しています。

 当然ながらデータセットとモデルの組み合わせによって特性は異なるので、「あるデータセットではこうだった」という参考程度にどうぞ。


用語


  • R-CNN: Region CNN

  • R-FCN: Region-based Fully Convolutional Networks

  • CNN: Convolutional Neural Network

  • SSD: Single Shot multibox Detector

  • mAP: mean Average Precision

  • IoU: Intersection over Union


環境

 学習、推論に用いた環境は以下の通りです。


  • ハードウェア:


    • CPU: Intel Core i5 7600

    • メモリ: 16GB

    • GPU: GeForce GTX1070 8GB



  • ソフトウェア:


    • OS: Ubuntu 18.04.3 LTS

    • Docker: 18.09.7

    • docker-compose: 1.24.1

    • nvidia-docker: 2.2.0

    • NVIDIAドライバ: 410.104

    • Python: 3.6.8

    • TensorFlow: 1.14.0

    • TensorFlow Object Detection API: コミットID 62184a96e740a3ecd65018acda42a11062b6d43d

    • COCO API: コミットID: 636becdc73d54283b3aac6d4ec363cffbb6f9b20

    • Pythonパッケージ:



      • Click: 7.0


      • contextlib2: 0.5.5


      • Cython: 0.29.13


      • opencv-python: 4.1.0.25


      • Pillow: 6.1.0






データセット

 今回使用したデータセットは独自のもので、残念ながら詳細はお伝えできません。規模は以下の通りです。


  • ラベル: 2種類

  • ラベル数(正解バウンディングボックス数):


    • ラベルA: 2,224

    • ラベルB: 47

    • 合計: 2,271



  • ラベル付けされた画像数(バウンディングボックスなしも含む): 2,274枚


    • うち、ラベルを含む画像数: 1,212枚



  • 学習データ/テストデータの割合: 9:1

 「ラベルB」のラベルが不足しているため十分な学習が行えておらず、平均精度に悪影響を及ぼしているかもしれません。ただ、今回は相対的な精度だけを見ており、絶対的な精度は見ていないのであまり影響ないものと思われます。

また、ラベルを含まない画像(ネガティブサンプル)は使用していません。

 蛇足ながら、ラベル付け(アノテーション)によって腱鞘炎(っぽい状態)になりました。みなさんもラベル付けに使うツール(ソフトウェア、ハードウェア)には十分に気を配り、ラベル付けを行いましょう。健康第一です。


ベースモデル

 今回はTensorFlow Object Detection APIのModel Zooで提供されている、COCOにより事前学習済みのモデルをベースとして使用しました。

ベースとしたモデルデータと設定ファイルは以下の通りです。

No
モデル
学習済みモデル
設定ファイル

1
Faster R-CNN
faster_rcnn_resnet101_coco
faster_rcnn_resnet101_coco.config

2
R-FCN
rfcn_resnet101_coco
rfcn_resnet101_coco.config

3
SSD
ssd_mobilenet_v2_coco
ssd_mobilenet_v2_coco.config


学習時間/推論時間

 今回はすべてのモデルにおいて30,000ステップの学習を行いました。また、データセットの1割、122枚をテストデータとして推論を行いました。

1回あたり10枚ずつ推論を行い、初回の推論時にはモデルのロードなどの初期化が行われています。そのため、初回を除く推論時間も併記しています。


  • SSDの推論時間は、Faster R-CNN、R-FCNの10分の1以下。

  • SSDの学習時間は、Faster R-CNN、R-FCNの2倍程度。

No
モデル
学習時間
推論全体
初回を除く110枚の推論
左記1枚あたり
初回を含む122枚の推論
左記1枚あたり

1
Faster R-CNN
155分
45.816500秒
34.694372秒
0.315403秒
43.957657秒
0.360308秒

2
R-FCN
146分
39.321194秒
28.740958秒
0.261281秒
37.311630秒
0.305833秒

3
SSD
295分
3.885033秒
1.333236秒
0.012120秒
2.947371秒
0.024158秒


定量的な精度

 30,000ステップ時点での評価結果は以下の通りです。TensorFlow Object Detection APIの評価方法coco_detection_metricsを使用しています。


  • Precision:


    • すべての項目においてSSD、R-FCN、Faster R-CNNの順番で精度が良い。



  • Recall:


    • SSDの方が基本的に良いが、R-FCNの方が良いこともある。



No
項目
Faster R-CNN
R-FCN
SSD

1
Average Precision (AP) @[ IoU=0.50:0.95, area= all, maxDets=100 ]
0.218
0.230
0.327

2
Average Precision (AP) @[ IoU=0.50 , area= all, maxDets=100 ]
0.419
0.439
0.717

3
Average Precision (AP) @[ IoU=0.75 , area= all, maxDets=100 ]
0.206
0.209
0.259

4
Average Precision (AP) @[ IoU=0.50:0.95, area= small, maxDets=100 ]
0.165
0.189
0.209

5
Average Precision (AP) @[ IoU=0.50:0.95, area=medium, maxDets=100 ]
0.245
0.247
0.486

6
Average Precision (AP) @[ IoU=0.50:0.95, area= large, maxDets=100 ]
0.505
0.545
0.534

7
Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets= 1 ]
0.160
0.179
0.289

8
Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets= 10 ]
0.271
0.396
0.375

9
Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets=100 ]
0.299
0.405
0.378

10
Average Recall (AR) @[ IoU=0.50:0.95, area= small, maxDets=100 ]
0.267
0.434
0.254

11
Average Recall (AR) @[ IoU=0.50:0.95, area=medium, maxDets=100 ]
0.290
0.291
0.535

12
Average Recall (AR) @[ IoU=0.50:0.95, area= large, maxDets=100 ]
0.558
0.583
0.600


定性的な精度

 正解データとモデル3つの推論結果の合計4枚を並べ、定性的な精度を確認してみました。数値では示せないので、参考程度にどうぞ。


  • 全体:


    • 全体的に検出精度は良好で今回の用途では実用的。


      • 特に対象物が正面から写っている場合は、ほぼ検出できている。



    • 対象物の側面しか写っていない場合は、検出できたりできなかったり。



  • Faster R-CNN:


    • もっとも精度が高い印象。



  • R-FCN:


    • 擬陽性(誤検出)が他のモデルに比べて多いように感じる。



  • SSD:


    • バウンディングボックスが大きめに出力されがち。

    • 偽陰性(検出漏れ)が他のモデルに比べて多いように感じる。

    • 小さい物体の検出精度が低め。




付録: Dockerfile

 今回、学習と推論はDocker(nvidiaランタイム)上で行いました。model_builder_test.pyより後のパッケージは推論処理で使っているだけで、TensorFlow Object Detection APIとしては不要です。

FROM tensorflow/tensorflow:1.14.0-gpu-py3-jupyter

RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
git-core \
protobuf-compiler \
&& rm --recursive --force /var/lib/apt/lists/*

RUN git clone https://github.com/tensorflow/models.git /opt/tensorflow/models \
&& cd /opt/tensorflow/models/ \
&& git checkout 62184a96e740a3ecd65018acda42a11062b6d43d \
&& cd /opt/tensorflow/models/research/ \
&& protoc --python_out . object_detection/protos/*.proto
ENV PYTHONPATH ${PYTHONPATH}:/opt/tensorflow/models/research
ENV PYTHONPATH ${PYTHONPATH}:/opt/tensorflow/models/research/slim

COPY requirements.txt /root/
RUN pip3 install --requirement /root/requirements.txt

RUN git clone https://github.com/cocodataset/cocoapi.git /opt/cocoapi \
&& cd /opt/cocoapi/ \
&& git checkout 636becdc73d54283b3aac6d4ec363cffbb6f9b20 \
&& cd /opt/cocoapi/PythonAPI/ \
&& make \
&& cp --recursive --verbose pycocotools /opt/tensorflow/models/research/

RUN cd /opt/tensorflow/models/research/ \
&& python3 object_detection/builders/model_builder_test.py

RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
libsm6 \
libxext6 \
libxrender-dev \
&& rm --recursive --force /var/lib/apt/lists/*
RUN pip3 install opencv-python==4.1.0.25


requirements.txt

Click==7.0

contextlib2==0.5.5
Cython==0.29.13
Pillow==6.1.0