Object Detection APIで簡単に物体検知を行ってみる(トレーニングまで)

# Object Detection APIで簡単に物体検知を行ってみる(トレーニングまで)

今年から物体検知などを仕事で使用しているエンジニアです。
今回Object Detection APIという物体検知を行うに当たり便利なものを紹介させていただきます！

## 対象者
物体検知を簡単に行いたい人

## 使用するリンク
Object Detection APIチュートリアル
[models/research/object_detection at master · tensorflow/models · GitHub](https://github.com/tensorflow/models/tree/master/research/object_detection)

## 前提
CentOS 7.4
Python3.6
virtualenv 16.0
pip 18.0

## 環境構築

下記リンクで記載されているとおりに環境構築をしていきます。
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md

tensorflowインストール
`pip install tensorflow`

GPU環境下の場合
`pip install tensorflow-gpu`

それぞれ各ツールインストール
`pip install Cython`
`pip install contextlib2`
`pip install pillow`
`pip install lxml`
`pip install jupyter`
`pip install matplotlib`

model/research配下で下記を実行
`protoc object_detection/protos/*.proto --python_out=.`
**※成功しても何も返って来ない**

パスを通す
``export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim``
**※成功しても何も返って来ない**

テスト実行
`python object_detection/builders/model_builder_test.py`
OK!という表示がされていれば、大丈夫です。

## サンプルコード動かす
ここまでくれば、サンプルコードが動くはずwなので、
下記のファイルを実行し、サンプルコードが動くかどうか確認してみてください。
models/research/object_detection/配下に
`object_detection_tutorial.ipynb`ファイルがあるので、それを実行してください。


## データダウンロード & TFRecord作成
###トレーニングするデータをダウンロード
結構ダウンロードするのに時間かかります(40分くらい)
下記2つをダウンロード
`wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz`
`wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz`

ダウンロードしたら下記コマンドで解凍
`tar -xvf images.tar.gz`
`tar -xvf annotations.tar.gz`

このannotationのデータが正解データであり、これを学習させます。
教師あり学習の教師の部分に該当します。

該当リンク
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_pets.md

### チュートリアルに記載されているフォルダ構成に設定
チュートリアルでは、下記のような構成が推奨されているのでそれに従います。
models/research/配下で行います。

+はフォルダ、
-はファイルを意味しています。
```+data
  -label_map file
  -train TFRecord file
  -eval TFRecord file
+/object_detection/models
  + model
    -pipeline config file
    +train
    +eval
```

### TFRecord作成
Object Detection APIはTensorflowで書かれているので、
Tensorflowが推奨するデータ形式に変換して、学習を行います。
先程ダウンロードしたデータを使用して、TFRecordというデータ形式に変換します。

tensorflow/models/research/配下で下記コマンドを実行
**下記コマンドはimages, annotationsフォルダが存在するフォルダで実行**

```sh
python object_detection/dataset_tools/create_pet_tf_record.py \
    --label_map_path=object_detection/data/pet_label_map.pbtxt \
    --data_dir=`pwd` \
    --output_dir=`pwd`
```


## トレーニング & TensorBord可視化
### 学習済モデルダウンロード
下記から学習済のモデルをダウンロードする
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md

モデルは、`ssd_mobilenet_v1_coco`を選択してください。
ここはconfigで選択した際の名前と同じ名前のモデルを選択します。
これは、学習済のモデルで、転移学習を行うので、このモデルをダウンロードしています。

### Configファイル設定
次はconfigファイルを設定します。
このvconfigファイルには、どのモデルを使用して、勾配降下法は何を使うかなど、いろいろ設定することができます。

configファイルは、下記に格納されています
`research/object_detection/samples/configs`

今回は、`ssd_mobilenet_v1_coco.config`を使用します。

configファイルで変更する箇所は4箇所です(※評価を含めない場合です)

- num_class
- fine_tune_checkpoint
- train_input_reader
- label_map_path

#### num_class
これは分類の数です。
今回`pet_label_map.pbtxt`を使用しており、ファイルの中身を見ると、idが37まであるのがわかります。

```
ssd { 
  num_classes: 37 # 分類する数
```

#### fine_tune_checkpoint
転移学習のモデルを指定している箇所です。

```
fine_tune_checkpoint: "該当するフォルダパス"
```

#### input_path
最後は、pet_faces_train.record* 指定する。
*は全てを意味します。

```
train_input_reader: {
  tf_record_input_reader {
    input_path: "設置しているフォルダのパス/pet_faces_train.record*"
  }
```

#### label_map_path
これはデータを分類するためのものがidと名前で保存されています。
何番のラベルがどのラベル(猫や犬)に該当しているのかを記載しています。
今回は、`pet_label_map.pbtxt`を使用します。

```
  label_map_path: "設置しているフォルダのパス/pet_label_map.pbtxt"
}
```

### トレーニング
models/object_detectionフォルダ配下において下記を実行。

```sh
python legacy/train.py 
--logtostderr 
--pipeline_config_path=該当するフォルダのパス/ssd_mobilenet_v1_pets.config #どのconfigファイルを使用するのか
--train_dir=models/train/ # どこのフォルダにトレーニングした情報を保存するのか
```
※最近Object Detection APIがアップデートされ、チュートリアルとコマンドが異なりますが、私は上記でも実行できました。


### Tensorboardで確認(任意)
下記のコードでTensorboardを起動することができます。
`tensorboard --logdir=train --port 6006`

デフォルトのポート：6006

## 学習したデータをExport
### Export 
学習が終了すると、指定したフォルダに下記の3つのファイルがトレーニング数毎にそれぞれ作成されていると思います。
今度はこれを使って学習したデータをExportしたいと思います。

```
model.ckpt-トレーニング数.data-00000-of-00001
model.ckpt-トレーニング数.index
model.ckpt-トレーニング数.meta 
```


/models/research/配下で下記を実行します。

```sh

python object_detection/export_inference_graph.py \
    --input_type=image_tensor \
    --pipeline_config_path= トレーニングで指定したpipline_configと同じフォルダの場所を指定 \
    --trained_checkpoint_prefix= model.ckptが存在するフォルダを指定\
    --output_directory= 
```
なおtrained_checkpoint_prefixは、model.ckpt-トレーニング数まで指定すれば大丈夫です。

Exportが完了すると、指定したフォルダに下記のようなファイルが保存されているはずです。
そして次に使用するのは、`frozen_inference_graph.pb`のみです。

```
checkpoint
frozen_inference_graph.pb
model.ckpt.data-00000-of-00001
model.ckpt.index
model.ckpt.meta
pipeline.config
saved_model
```

### Exportしたモデルを実行

Exportしたfrozonモデルを使って、実際どのくらいの精度がでているのか見てみましょう。
/research/object_detection配下に`object_detection_tutorial.ipynb`ファイルがあるので、開きます。

修正する箇所は2箇所です。

#### Variables
```ini
使用しないので、コメントアウトしておく
#MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
#MODEL_FILE = MODEL_NAME + '.tar.gz'
#DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'

exportしたフォルダの位置を指定する
PATH_TO_FROZEN_GRAPH = MODEL_NAME + '/frozen_inference_graph.pb'

# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('data', 'pet_label_map.pbtxt')

NUM_CLASSES = 37
```

#### Download Model
ここはすべてコメントアウトで問題ないです。

これで問題なく実行できるはずです！