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
Click==7.0
contextlib2==0.5.5
Cython==0.29.13
Pillow==6.1.0