M2Detで物体検出やってみた

# はじめに
物体検出について調べる必要があり、ずぶの素人な私には理解は難しい！とりあえず動かしてみよう！となりました。そこで、「最新最強の物体検出」と[こちらの記事](https://qiita.com/kzykmyzw/items/c6a66e2c03c917cff36b)で紹介されていた"M2Det"という手法を触ってみました。
導入手順で手間取ってしまったので、できるだけ丁寧に書いておきたいと思います。


# 環境

- Azure VM
    - Standard NV6_Promo (6 vcpu 数、56 GiB メモリ)
    - Linux (ubuntu 18.04)

# 実装/環境構築
## VM
ちょっと試してみて終わったら破棄すればいいや～という考えでAzure上にVMを建てることにしました。

[Azure Portal](https://azure.microsoft.com/ja-jp/features/azure-portal/)からリソースの作成 > Ubuntu Server 18.04 LTSを選択して適当な内容を入力していきます。
![AzurePortalVM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/38a1b34d-d0e3-7aaa-ae6a-ea2ca23979a2.png)

デプロイが完了したらリソースへ移動して接続 > sshコマンドをコピーします。
![AzureVMssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/2ab8fad6-5d45-b460-ab0a-9248abbfa9d7.png)

このままではVMのポート22が開放されていないため、ネットワーク > 受信ポートの規則を追加する でポート22を開放しておきます。
![AzureVMport.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/879e4fbc-0017-2269-8237-27cad2b12efd.png)


準備ができたので、コマンドプロンプトにコピーしたコマンドを貼り付けてSSH接続します。

SSH接続ができたらリモートデスクトップ接続します。
こちらの記事がわかりやすく解説されていました。手順通り進めれば問題なくできるかと思います。
[https://qiita.com/hiro871_/items/0086ea75518ec754b90d](https://qiita.com/hiro871_/items/0086ea75518ec754b90d)

Azure PortalからRDPファイルをダウンロードしてくると楽にリモートデスクトップ接続ができます。（実行するだけで接続できる）
![AzureVMRDP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/295a2f38-9eac-9310-1091-9d33ec693707.png)

ここからはリモートデスクトップ上で作業を進めます。
ターミナルはここから開けます。
![RDPterminal.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/e90e3691-61c2-2337-1fae-438f8a55674a.png)


## M2Det
論文の著者のgithubのREADMEに従って必要なものをインストールしていきます。
[https://github.com/qijiezhao/M2Det](https://github.com/qijiezhao/M2Det)

M2Detはディープラーニングフレームワークのpytorchで実装されているため、pytorchやその周辺ライブラリを落とす必要があります。
> Anaconda is our recommended package manager since it installs all dependencies. 
(Anacondaは、すべての依存関係をインストールするため、推奨されるパッケージマネージャです。)

と[公式HP](https://pytorch.org/)にもあるようにREADMEでもanacondaでpython環境を準備するとあります。
anacondaの[ダウンロードページ](https://www.anaconda.com/distribution/)からpython3.Xのインストーラーをダウンロード、インストールします。

```
bash Anaconda3-2019.03-Linux-x86_64.sh
```
ライセンス許諾やインストール場所、パスを通すかを聞かれますが全てデフォルト(ENTER)で進めます。
パスを通してしまうと常にanacondaのコマンドが使用されてしまうため、anacondaを使用するときだけ`export`するようにします。

```
 export PATH=/home/<username>/anaconda3/bin/:$PATH 
```
次はGPUのドライバーをインストールします。NVIDIAの[CUDAダウンロードページ](https://developer.nvidia.com/cuda-10.1-download-archive-base?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=debnetwork)から自分の使用しているUbuntuのバージョンにあったインストーラーをページの手順通りにダウンロード&インストールします。

```
sudo dpkg -i cuda-repo-ubuntu1804_10.1.105-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo apt-get update
sudo apt-get install cuda
```


pytorchのインストールです。githubのREADMEのコマンドをそのままペーストするとエラーが出てしまいます。バージョン指定の`==`の前後のスペースを消しましょう。

```
$ conda install pytorch==0.4.1 torchvision -c pytorch
```
oepncv-pythonとtqdmをインストールします。tqdmは実行の進捗状況をバーで表示するためのパッケージです。

```
pip install opencv-python tqdm
```

githubからM2Detのソースをクローンしてきます。

```
git clone https://github.com/qijiezhao/M2Det.git
```
`M2Det`ディレクトリに入り`make.sh`を実行します。

```
$ cd M2Det/
$ sh make.sh
```
データセットを用意します。[github](https://github.com/amdegroot/ssd.pytorch)からソースをクローンし、好きなデータセットをダウンロードします。私はCOCOをダウンロードしました。

```
$ git clone https://github.com/amdegroot/ssd.pytorch.git
$ cd ssd.pytorch/
$ sh data/scripts/COCO2014.sh
```
最後に重みづけファイルをダウンロードします。
([baidu cloud](https://pan.baidu.com/s/1LDkpsQfpaGq_LECQItxRFQ),[google drive](https://drive.google.com/file/d/1NM1UDdZnwHwiNDxhcP-nndaWj24m-90L/view?usp=sharing)) 
重みづけファイルは`M2Det/weights/`以下に配置してください。

```
$ mkdir weights
$ mv m2det512_vgg.pth weights/
```

それでは、やっとのことで実行！

```
$ python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show
Traceback (most recent call last):
  File "demo.py", line 8, in <module>
    from configs.CC import Config
  File "/home/dluser/M2Det/configs/CC.py", line 7, in <module>
    from addict import Dict
ModuleNotFoundError: No module named 'addict'
```
エラー......
足りないモジュールは`pip install`しましょう。

```
$ pip install addict
```

改めて実行するとデモ用の画像を解析してくれました。

```
$ python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show
 ----------------------------------------------------------------------
|                       M2Det Demo Program                             |
 ----------------------------------------------------------------------
The Anchor info:
{'feature_maps': [64, 32, 16, 8, 4, 2], 'min_dim': 512, 'steps': [8, 16, 32, 64, 128, 256], 'min_sizes': [30.72, 76.8, 168.96, 261.12, 353.28, 445.44], 'max_sizes': [76.8, 168.96, 261.12, 353.28, 445.44, 537.6], 'aspect_ratios': [[2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]], 'variance': [0.1, 0.2], 'clip': True}
===> Constructing M2Det model
Loading resume network...
===> Finished constructing and loading model
pos:(2.0,146.5,36.2,273.8), ids:person, score:0.972
pos:(41.9,124.6,118.1,344.2), ids:person, score:0.913
pos:(123.3,142.2,181.3,355.8), ids:person, score:0.667
pos:(94.8,148.4,134.6,264.5), ids:person, score:0.506
pos:(43.7,141.8,70.7,191.0), ids:person, score:0.447
pos:(94.2,145.9,111.8,166.7), ids:person, score:0.128
pos:(38.6,127.3,111.5,342.4), ids:person, score:0.124
pos:(32.5,146.8,65.7,286.9), ids:person, score:0.120

(略)
```
![M2Det.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/955fe513-141d-ae16-24f1-c6f254b8a5a1.png)


# 感想
0から環境を作るのは結構大変だった...。
今回はデモ用のプログラムを実行しただけだったけど、pythonファイルを書き換えれば自分の画像を解析したり画像を保存したりできると思うので（というかそれがメインの使用用途だと思うので）やってみたいと思います！まずはpythonの勉強から...！