独自データセットによるOne Class tiny-YoloV3のローカルトレーニングとOpenVINOへの対応（30分インスタント麺）

**OpenVINO-YoloV3**　[![GitHub stars1](https://img.shields.io/github/stars/PINTO0309/OpenVINO-YoloV3.svg?style=social&label=Stars)](https://github.com/PINTO0309/OpenVINO-YoloV3)
<a href="https://github.com/PINTO0309/OpenVINO-YoloV3"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/PINTO0309/OpenVINO-YoloV3.png" width="460px"></a>
<font color="red">**I wrote an English article, [here](https://qiita.com/PINTO/items/7dd7135085a7249bf17a#support-for-local-training-and-openvino-of-one-class-tiny-yolov3-with-a-proprietary-data-set)**</font>

# １．はじめに
私のYoloV3リポジトリへの独自データセットに関する海外エンジニアからのissueが多すぎてやかましいため、この場で検証を兼ねて適当な手順をメモとして残すものです。
Qiita上には素晴らしい手順を整理してみえる方々がたくさんいらっしゃいますので、そちらを参照いただくことをオススメします。
皆さんと私の手順で異なる部分は、 Intel の OpenVINO へストレートに対応させる手順を含むことです。

今更ローカルで学習するなんて旧石器時代みたいなことしてる、とか冷たいことを言わないでください。
Darknetの学習だけにとどまらない環境構築手順になりますので、空の上に出ると逆に面倒きわまりなかっただけです。

完全にメモとして残しますので文章でウダウダと解説いたしません。
**`Personクラス`** だけで簡易トレーニングします。

# ２．環境

- Ubuntu 16.04 x86_64
- Geforce GTX 1070
- Core i7
- NVIDIA Driver Version: 396.54 
- CUDA 9.0
- CuDNN 7.2.1
- VoTT 1.7.2 (楽にアノテーションしたい方は他のツールをオススメします)
- OpenCV 4.0.1-openvino
- Tensorflow GPU v1.12.0

# ３．独自データセットによる学習環境構築

```console:darknetのビルド
$ cd ~
$ git clone https://github.com/pjreddie/darknet.git
$ cd darknet
$ nano Makefile

GPU=1
CUDNN=1
OPENCV=1
OPENMP=0
DEBUG=0

$ make
```

```console:snapdとVoTTのインストール
$ cd ~
$ sudo apt install -y snapd
$ wget https://github.com/Microsoft/VoTT/releases/download/v1.7.2/vott-linux.snap
$ sudo snap install --dangerous vott-linux.snap
```

```console
$ cd ~
$ mkdir vott
# ココでvottフォルダ配下に学習させたい画像をコピーしておく
```
**`VoTT. パイルダーオン！！`**
![Screenshot 2019-03-16 22:00:52.png](https://qiita-image-store.s3.amazonaws.com/0/194769/f7649104-45d6-a551-0330-5e769e6f9c71.png)
![Screenshot 2019-03-16 22:02:04.png](https://qiita-image-store.s3.amazonaws.com/0/194769/ff153b31-f147-742d-758e-b0e4d5f07b7d.png)
![Screenshot 2019-03-16 22:04:28.png](https://qiita-image-store.s3.amazonaws.com/0/194769/27a89afe-64e9-3343-0581-e5fc7a41913d.png)
![Screenshot 2019-03-16 22:06:11.png](https://qiita-image-store.s3.amazonaws.com/0/194769/ac7b4e9f-e2df-a865-c191-9f10198dedbc.png)
![Screenshot 2019-03-16 22:12:40.png](https://qiita-image-store.s3.amazonaws.com/0/194769/df2c4655-cce2-76d8-9ddd-03730091146e.png)
![Screenshot 2019-03-16 22:13:35.png](https://qiita-image-store.s3.amazonaws.com/0/194769/23ce7b00-6b9b-ef47-0478-f01327ed6861.png)
![Screenshot 2019-03-16 22:15:42.png](https://qiita-image-store.s3.amazonaws.com/0/194769/68514a7c-15ce-416e-7850-06e12504e49f.png)
![Screenshot 2019-03-16 22:18:09.png](https://qiita-image-store.s3.amazonaws.com/0/194769/09a557f8-d5d9-2d55-09a7-943b8c198764.png)
![Screenshot 2019-03-16 22:18:42.png](https://qiita-image-store.s3.amazonaws.com/0/194769/cf95a996-1492-8951-9419-e7bfbb76222d.png)
![Screenshot 2019-03-16 22:20:12.png](https://qiita-image-store.s3.amazonaws.com/0/194769/030e76fc-30b9-cd30-ceae-bc892b56e2b7.png)


```console:dataフォルダをdarknetフォルダ配下へコピー
$ cd ~
$ mv darknet/data darknet/_data
$ cp -r vott/data darknet
```

```console:cfgファイルの調整
$ cp darknet/cfg/yolov3-tiny.cfg darknet/cfg/yolov3-tiny-mine.cfg
$ nano darknet/cfg/yolov3-tiny-mine.cfg
```

<details><summary>**yolov3-tiny-mine.cfgの修正内容**</summary><div>

filters = (classes  +5) * 3

```txt:yolov3-tiny-mine.cfg
[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=4
subdivisions=1
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001
burn_in=1000
max_batches = 500200
policy=steps
steps=400000,450000
scales=.1,.1

[convolutional]
batch_normalize=1
filters=16
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=1

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky

###########

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
#filters=(classes+5)*3
size=1
stride=1
pad=1
filters=18
activation=linear



[yolo]
mask = 3,4,5
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1

[route]
layers = -4

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = -1, 8

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
#filters=(classes+5)*3
size=1
stride=1
pad=1
filters=18
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
```

</div></details>

```console:事前トレーニング済みの重みデータダウンロード
$ cd ~/darknet
$ wget https://pjreddie.com/media/files/darknet53.conv.74
```

```console:tiny-YoloV3のトレーニング実行
$ ./darknet detector train data/obj.data cfg/yolov3-tiny-mine.cfg darknet53.conv.74
```
![Screenshot 2019-03-16 23:58:33.png](https://qiita-image-store.s3.amazonaws.com/0/194769/dddac6ef-7c68-0fc4-2410-956f9ea929f2.png)
![Screenshot 2019-03-17 00:01:49.png](https://qiita-image-store.s3.amazonaws.com/0/194769/1d121670-54da-87a4-dbc9-ed3b9468d649.png)

```console:各種ファイルの場所まとめ
/home/b920405/darknet/cfg/yolov3-tiny-mine.cfg
/home/b920405/darknet/data/obj.data
/home/b920405/darknet/data/obj.names
```

# ４．Darknet (.weights) -> Tensorflow (.pb) -> OpenVINO (.bin)

```console:Darknet->Tensorflow
$ cd ~
$ git clone https://github.com/PINTO0309/OpenVINO-YoloV3.git
$ cd OpenVINO-YoloV3
$ cp ~/darknet/backup/yolov3-tiny-mine_10000.weights weights
$ echo 'person' > yolov3-tiny-mine.names
$ python3 convert_weights_pb.py \
--class_names yolov3-tiny-mine.names \
--weights_file weights/yolov3-tiny-mine_10000.weights \
--data_format NHWC \
--tiny \
--output_graph pbmodels/frozen_yolov3-tiny-mine.pb
```

![frozen_yolov3-tiny-mine.png](https://qiita-image-store.s3.amazonaws.com/0/194769/577fe6af-9127-62d9-1bc7-d4de1590bdf1.png)

```console:FP32の場合：Tensorflow(.pb)->OpenVINO(.bin)変換
$ sudo python3 /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/mo_tf.py \
--input_model pbmodels/frozen_yolov3-tiny-mine.pb \
--output_dir lrmodels/tiny-YoloV3/FP32 \
--data_type FP32 \
--batch 1 \
--tensorflow_use_custom_operations_config yolo_v3_tiny_changed.json
```

```console:FP16の場合：Tensorflow(.pb)->OpenVINO(.bin)変換
$ sudo python3 /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/mo_tf.py \
--input_model pbmodels/frozen_yolov3-tiny-mine.pb \
--output_dir lrmodels/tiny-YoloV3/FP16 \
--data_type FP16 \
--batch 1 \
--tensorflow_use_custom_operations_config yolo_v3_tiny_changed.json
```

![Screenshot 2019-03-17 00:23:13.png](https://qiita-image-store.s3.amazonaws.com/0/194769/66e4491b-2577-a24a-a5f0-893bfb1e436a.png)

# ５．おわりに
おいっ！！ ひとつも躓かずに３０分で一発成功したやないかい！！
やはり、海外のエンジニアは、アレですな。


# Support for local training and OpenVINO of One Class tiny-YoloV3 with a proprietary data set
## １．introduction
Simple training with only **`Person class`**.

## ２．Environment

- Ubuntu 16.04 x86_64
- Geforce GTX 1070
- Core i7
- NVIDIA Driver Version: 396.54 
- CUDA 9.0
- CuDNN 7.2.1
- VoTT 1.7.2
- OpenCV 4.0.1-openvino
- Tensorflow GPU v1.12.0

## ３．Learning environment construction by original data set

```console:darknet_build
$ cd ~
$ git clone https://github.com/pjreddie/darknet.git
$ cd darknet
$ nano Makefile

GPU=1
CUDNN=1
OPENCV=1
OPENMP=0
DEBUG=0

$ make
```

```console:Install_snapd_and_VoTT
$ cd ~
$ sudo apt install -y snapd
$ wget https://github.com/Microsoft/VoTT/releases/download/v1.7.2/vott-linux.snap
$ sudo snap install --dangerous vott-linux.snap
```

```console
$ cd ~
$ mkdir vott
# Copy the image you want to learn under vott folder here
```
![Screenshot 2019-03-16 22:00:52.png](https://qiita-image-store.s3.amazonaws.com/0/194769/f7649104-45d6-a551-0330-5e769e6f9c71.png)
![Screenshot 2019-03-16 22:02:04.png](https://qiita-image-store.s3.amazonaws.com/0/194769/ff153b31-f147-742d-758e-b0e4d5f07b7d.png)
![Screenshot 2019-03-16 22:04:28.png](https://qiita-image-store.s3.amazonaws.com/0/194769/27a89afe-64e9-3343-0581-e5fc7a41913d.png)
![Screenshot 2019-03-16 22:06:11.png](https://qiita-image-store.s3.amazonaws.com/0/194769/ac7b4e9f-e2df-a865-c191-9f10198dedbc.png)
![Screenshot 2019-03-16 22:12:40.png](https://qiita-image-store.s3.amazonaws.com/0/194769/df2c4655-cce2-76d8-9ddd-03730091146e.png)
![Screenshot 2019-03-16 22:13:35.png](https://qiita-image-store.s3.amazonaws.com/0/194769/23ce7b00-6b9b-ef47-0478-f01327ed6861.png)
![Screenshot 2019-03-16 22:15:42.png](https://qiita-image-store.s3.amazonaws.com/0/194769/68514a7c-15ce-416e-7850-06e12504e49f.png)
![Screenshot 2019-03-16 22:18:09.png](https://qiita-image-store.s3.amazonaws.com/0/194769/09a557f8-d5d9-2d55-09a7-943b8c198764.png)
![Screenshot 2019-03-16 22:18:42.png](https://qiita-image-store.s3.amazonaws.com/0/194769/cf95a996-1492-8951-9419-e7bfbb76222d.png)
![Screenshot 2019-03-16 22:20:12.png](https://qiita-image-store.s3.amazonaws.com/0/194769/030e76fc-30b9-cd30-ceae-bc892b56e2b7.png)


```console:Copy_data_folder_to_darknet_folder
$ cd ~
$ mv darknet/data darknet/_data
$ cp -r vott/data darknet
```

```console:cfg_file_adjustment
$ cp darknet/cfg/yolov3-tiny.cfg darknet/cfg/yolov3-tiny-mine.cfg
$ nano darknet/cfg/yolov3-tiny-mine.cfg
```

<details><summary>**Modification of yolov3-tiny-mine.cfg**</summary><div>

filters = (classes  +5) * 3

```txt:yolov3-tiny-mine.cfg
[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=4
subdivisions=1
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001
burn_in=1000
max_batches = 500200
policy=steps
steps=400000,450000
scales=.1,.1

[convolutional]
batch_normalize=1
filters=16
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=1

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky

###########

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
#filters=(classes+5)*3
size=1
stride=1
pad=1
filters=18
activation=linear



[yolo]
mask = 3,4,5
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1

[route]
layers = -4

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[upsample]
stride=2

[route]
layers = -1, 8

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
#filters=(classes+5)*3
size=1
stride=1
pad=1
filters=18
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=1
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
```

</div></details>

```console:Pre-trained_weight_data_download
$ cd ~/darknet
$ wget https://pjreddie.com/media/files/darknet53.conv.74
```

```console:Training_run_of_tiny-YoloV3
$ ./darknet detector train data/obj.data cfg/yolov3-tiny-mine.cfg darknet53.conv.74
```
![Screenshot 2019-03-16 23:58:33.png](https://qiita-image-store.s3.amazonaws.com/0/194769/dddac6ef-7c68-0fc4-2410-956f9ea929f2.png)
![Screenshot 2019-03-17 00:01:49.png](https://qiita-image-store.s3.amazonaws.com/0/194769/1d121670-54da-87a4-dbc9-ed3b9468d649.png)

```console:Location_summary_of_various_files
/home/b920405/darknet/cfg/yolov3-tiny-mine.cfg
/home/b920405/darknet/data/obj.data
/home/b920405/darknet/data/obj.names
```

# ４．Darknet (.weights) -> Tensorflow (.pb) -> OpenVINO (.bin)

```console:Darknet->Tensorflow
$ cd ~
$ git clone https://github.com/PINTO0309/OpenVINO-YoloV3.git
$ cd OpenVINO-YoloV3
$ cp ~/darknet/backup/yolov3-tiny-mine_10000.weights weights
$ echo 'person' > yolov3-tiny-mine.names
$ python3 convert_weights_pb.py \
--class_names yolov3-tiny-mine.names \
--weights_file weights/yolov3-tiny-mine_10000.weights \
--data_format NHWC \
--tiny \
--output_graph pbmodels/frozen_yolov3-tiny-mine.pb
```

![frozen_yolov3-tiny-mine.png](https://qiita-image-store.s3.amazonaws.com/0/194769/577fe6af-9127-62d9-1bc7-d4de1590bdf1.png)

```console:In_the_case_of_FP32：Tensorflow(.pb)->OpenVINO(.bin)_convertion
$ sudo python3 /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/mo_tf.py \
--input_model pbmodels/frozen_yolov3-tiny-mine.pb \
--output_dir lrmodels/tiny-YoloV3/FP32 \
--data_type FP32 \
--batch 1 \
--tensorflow_use_custom_operations_config yolo_v3_tiny_changed.json
```

```console:In_the_case_of_FP16：Tensorflow(.pb)->OpenVINO(.bin)_convertion
$ sudo python3 /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/mo_tf.py \
--input_model pbmodels/frozen_yolov3-tiny-mine.pb \
--output_dir lrmodels/tiny-YoloV3/FP16 \
--data_type FP16 \
--batch 1 \
--tensorflow_use_custom_operations_config yolo_v3_tiny_changed.json
```

![Screenshot 2019-03-17 00:23:13.png](https://qiita-image-store.s3.amazonaws.com/0/194769/66e4491b-2577-a24a-a5f0-893bfb1e436a.png)