Docker版のRefineDetで物体検出してみる

#RefineDetとは
Single-Shot **Refine**ment Neural Network for Object **Det**ection ⇒ **RefineDet**
(Shifeng Zhang, Longyin Wen, Xiao Bian, Zhen Lei, Stan Z. Li：**2017/11/18**) 

ソースは[こちら](https://github.com/sfzhang15/RefineDet)から。

物体検出アルゴリズムのひとつで、SSDよりやや速度は劣るが、認識精度が高い。
**Two-Step Cascaded Regression**という仕組みで、
より小さな物体に対しての認識が可能なようです。

※以下の記事で日本語でも解説されているので、是非ご一読ください。
[リアルタイム物体検出向けニューラルネット、SSD(Single Shot Multi Detector)及びその派生モデルの解説](http://segafreder.hatenablog.com/entry/2018/03/11/152515)

その他のアルゴリズムと比べるとこんな感じ。

|       System       | VOC2007 test mAP  |FPS (Titan X)| 
|:-------------------|------------------:|------------:|
|Faster R-CNN(VGG16) |  73.2             | 7           |
|YOLO(GoogLeNet)     |  63.4             | 45          |
|YOLOv2(Darknet-19)  |  78.6             | 40          |
|SSD300(VGG16)       |  77.2             | 46          |
|SSD512(VGG16)       |  79.8             | 19          |
|RefineDet320(VGG16) |  80.0             | 40          |
|RefineDet512(VGG16) |  81.8             | 24          |
システム名に続く数字は入力サイズです。

# 実行環境
OS:Ubuntu16.04
GPU:GeForce GTX 1080
Docker:18.06.1-ce

#実行手順　
<ol><li>RefineDetリポジトリをクローンする。

```ruby:Terminal
$ git clone https://github.com/sfzhang15/RefineDet.git
```
</li><li>Dockerイメージを作成する。　
※CPU版は通常の```docker build```でOKです。
その場合、dockerfileディレクトリもCPU版のものを指定してください。

```ruby:Terminal
$ nvidia-docker build -t [任意のイメージ名] [RefineDetのGPU版dockerfileディレクトリ]
```

</li><li>Dockerコンテナを作成する。
※CPU版は```--runtime=nvidia```は不要です。
また2～4行目ではX Window Systemの設定を行っています。(画像表示のため)

```ruby:Terminal
$ docker run -it --runtime=nvidia \
      --net host \
      -e DISPLAY=$DISPLAY \
      -v $HOME/.Xauthority:/root/.Xauthority \
      --name [任意のコンテナ名] [作成したイメージ名]
```

</li><li>学習モデルをDLする。

学習モデルは[GitHub](https://github.com/sfzhang15/RefineDet)のREADME下部、ModelsよりDLできます。
今回は**PASCAL VOC models (VGG-16)** の **07+12 : RefineDet320**を使用します。

DLしたファイルを解凍し、Dockerコンテナの```/opt/caffe/```にコピーします。
```docker cp```でホスト⇔コンテナ間のコピーが可能です。

```ruby:Terminal
$ docker cp [Modelsディレクトリ] [コンテナ名]:/opt/caffe/
```

</li><li>Dockerコンテナに入り、必要なライブラリをインストールする。
```docker start [コンテナ名]``` ⇒ ```docker attach [コンテナ名]```でDockerコンテナに入れます。

Dockerコンテナに入ったら、カレントディレクトリを```/opt/caffe/```に変更してください。
またインストール前に```apt-get```を更新してください。

```ruby:Terminal
$ pip install matplotlib
$ apt-get install python-tk
$ pip install scikit-image
```

</li><li>RefineDetを実行する。

```ruby:Terminal
$ python ./test/refinedet_demo.py
```
![Screenshot from 2018-08-29 11-29-37.png](https://qiita-image-store.s3.amazonaws.com/0/265258/32a60668-bc39-64f9-6efe-e3fec3b3745e.png)
![Screenshot from 2018-08-29 11-29-45.png](https://qiita-image-store.s3.amazonaws.com/0/265258/28676396-e4cd-fa35-c90e-f1a05d293e8a.png)
![Screenshot from 2018-08-29 11-29-51.png](https://qiita-image-store.s3.amazonaws.com/0/265258/13a57a42-6b26-103d-0c11-6198e51c79ea.png)
![Screenshot from 2018-08-29 11-29-58.png](https://qiita-image-store.s3.amazonaws.com/0/265258/c6a2fac4-877b-aa3a-53f4-e14f088cd1d9.png)
![Screenshot from 2018-08-29 11-30-03.png](https://qiita-image-store.s3.amazonaws.com/0/265258/4296e435-d142-0ac8-0b88-4d1eb3a6754a.png)
画像が表示されれば成功です。
バスの運転手や後方の馬、人物など、
画像サイズに対して小さな物体も検出できていることがわかります。

#まとめ
普段は物体検出アルゴリズムにSSDを使用していますが、
小さな物体の認識精度が上がらず、試験的にRefineDetを使用しました。

今回はデモの実行のみですが、今後に期待が持てそうな結果となりました。
引き続き調査を続けていきたいと思います。

#参考文献
以下の記事がたいへん参考になりました。

- [caffeベースで配布されているネットワークをdockerで試す、Refinedetを題材に](http://segafreder.hatenablog.com/entry/2018/05/08/231451)
- [Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105)
- [GitHub(sfzhang15/RefineDet)](https://github.com/sfzhang15/RefineDet)