Watson Studio で YOLO V3 カスタム物体検出

[前回](https://qiita.com/schiyoda/items/d9e75bac0923996d1ac0)の記事ではYOLO V3のKeras版をWatson Studioで動かして、学習済みモデルを使用した物体検出をやってみました。今回はこのモデルを自前の画像で学習させて任意のモノを検出するカスタム物体検出に挑戦します。大きな流れとしては以下のようになります。

1. 教師データの作成
検出したい物体をアノテーションツールで学習させて教師データを作成します

2. YOLOモデルの学習
Watson StudioのDLaaS(Deep Learning as a Service)機能を使ってYOLOモデルを学習します

3. 物体検出
作成したモデルを使ってカスタム物体検出を実行します

今回も学習のためのコードは以下のものを参考にしています。
https://github.com/experiencor/keras-yolo3

# 1. 教師データの作成
今回は以下のような「IBM Watson」のアバターを新旧の区別も含めて検出できるか試してみたいと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/6c0a600f-41cb-72a0-7c28-b8230ad9a7bf.png)

まずは、画像のアノテーションツールを使ってロゴを学習させていきます。画像のアノテーションツールはさまざまものがありますが、私は[labelImg](https://github.com/tzutalin/labelImg)を使用しました。導入手順はリンク先の他、色々なところで紹介されているので割愛します。学習のための画像をWeb等で収集した上で、labelImg で watson および watson_others をアノテーションしていきます。アノテーション結果は Pascal VOC 形式で出力します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/09f417bb-27b7-78fc-ada9-5c7a4ffc96ff.png)

学習で使用した画像とアノテーション結果を[Git](https://github.com/schiyoda/YOLOV3-Keras-Custom)に置いているので、引き続きの手順はこちらをgit clone して使用します。

```console
git clone https://github.com/schiyoda/YOLOV3-Keras-Custom.git
```

> labelImg の 「Open Dir」メニューで images フォルダーを、「Change Save Dir」で annotations フォルダー指定することで、アノテーションした結果を参照可能です。

# 2. YOLOモデルの学習
アノテーションしたデータを使用してYOLOモデルをWatson StudioのDLaaS機能で学習します。

### 学習済み重みデータの取得
学習を早く完了されるために、学習済み重みデータを取得します。以下リンク先より backend.h5 ファイルを train フォルダにダウンロードします。

~~https://1drv.ms/u/s!ApLdDEW3ut5fgQXa7GzSlG-mdza6~~
http://www.mediafire.com/file/l1b96fk7j18yi7v/backend.h5

### 学習用のデータのアップロード
ICOS(IBM Cloud Object Storage)にバケットを作成した上で、学習用のデータをアップロードします。バケットの作成は以下等を参照してください。

https://qiita.com/schiyoda/items/c1fe7438e50087ff97ef

アップロード後のフォルダ構成は以下のようになっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/7aa34efe-320a-103e-bb71-05b7b0900a79.png)

### 学習の実行
Watson Studioで適当なプロジェクトを作成します。プロジェクトのSettingsタブからWatson Machine Learningのサービスを紐付けておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/c529c17e-ccd1-0a16-fe42-20ad0d6877e7.png)

プロジェクトのページに戻り、新規 Experiment を作成します。

Cloud Object Storage bucket for storing training source files、Cloud Object Storage bucket for storing results には先ほど学習用のデータをアップロードしたバケットを指定します。

> ICOSへのConnectionが作成されていない場合は New connectionタブから作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/e7721115-c9b1-ac88-f377-290d16ba0772.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/4b887250-9584-0a2c-15bf-865e23609d46.png)をクリックし、training definition を作成します。

- Name: 適当な名前を入力
- Training source code: [Git](https://github.com/schiyoda/YOLOV3-Keras-Custom)からダウンロードした zip ファイル（yolov3-keras-custom.zip）
- Framework: tensorflow 1.5
- Execution command: 

```console
pip install opencv-python-headless && python train.py -c config.json
```

- Compute plan: K80 (1 GPU)

> 今回は watson/watson_others というラベルで学習させていますが、別のデータで学習させたい場合は、zip ファイル中の config.json の以下のフィールドを変更してください。

>```console
> "labels":   ["watson","watson_others"]
>```

設定が完了したら以下の画面で Create and run をクリックし、学習を開始します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/dafc6242-cb6c-0013-0d2d-7180a54c2737.png)

学習が開始すると、以下のよう学習曲線や実行のログや参照可能です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/2491cfef-6a97-92c5-9376-ce5a843aff10.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/31e470eb-1400-b026-9f11-ab72fe7f743e.png)

# 3. 物体検出
### モデルのデプロイ
学習が完了（Completed）したら、モデルを保存（Save model）します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/bd11c4be-9d91-5e42-7ff1-11c0b6de2615.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/a604fa7f-9782-f093-922e-4745948b97b2.png)

プロジェクトのページに戻ると Watson Machine Learning models にモデルが保管されたことが分かるので、モデル名をクリックします。

Deployments タブから Add Deployment をクリックし、適当な名前をつけてSave します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/79bb3a29-f8b5-87ac-e5a3-38b6ebda259c.png)

STATUS が DEPLOY_SUCCESS となったらデプロイ完了です。

デプロイすると、モデルを呼び出すための Scoring End Point やアプリ作成に使えるCode Snippetが生成されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/dcfdff70-be21-8d8e-e251-e693460695cd.png)

### 物体検出のテスト
Watson Studioでプロジェクトを作成して、以下リンク先から Notebook を作成します。
https://github.com/schiyoda/YOLOV3-Keras-Custom/blob/master/yolov3_keras_custom.ipynb

Notebookでは上記のCode SnippetでデプロイしたWebサービスをコールして物体検出を実行します。いくつかの画像で試してみると以下のように物体検出できることが確認できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/dbc3b6dc-d362-c9f5-5295-49f800f34b7b.png)