YoloV4 のさまざまな実装 -調査中-


YoloV4 についてもさまざま実装が出てきているようだ。

## 各種実装を調査する理由
- ターゲットデバイスで高速に動作する実装を利用したい。
- そうするとモデルを変換する仕組みのあるyolov4の実装を利用したい。
- Yolov4の学習を、大本のdarknetとは違うdata 拡張 のしくみを利用して効果的に学習したい。
そういった目的があって、各種実装を調査している。


## Yolov3 とYoloV4の比較を紹介している記事
### [物体認識モデルYOLOv3を軽く凌駕するYOLOv4の紹介])
(https://blog.seishin55.com/entry/2020/05/16/183132
どのようにyolov4で検出精度をあげているのか説明している。

推論時のネットワークの構造だけが設定ファイルに書かれているのでなく、学習条件も書かれている。
学習時のdata augmentation についても書かれているので、上記のブログの内容を確かめているといいだろう。
活性化関数にMish acrivationを使ってるので、

```
activation=mish
...

```
の行が記述されている。

> bboxのregression loss
    CIoU-loss
    DIoU-NMS
に関連して
```
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6
```
の行も見受けられる。

このように、yolov3.cfg とyolov4.cfg との設定ファイルの違いと関連付けて読むといいだろう。


その中で、Jetson Xavierについて紹介している。
[Best way to use YOLO on Jetson Xavier with max FPS](https://github.com/AlexeyAB/darknet/issues/5386)


[XavierNX上でyolov3, yolov3-spp, yolov4を比較](https://qiita.com/sowd0726/items/db3c38a946fa883e416f)

![Screenshot from 2020-09-27 20-52-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/8ce76f8f-2570-181b-0033-e8995edb69f1.png)
表：　上記の記事から引用

----
### [Jetson Xavier NX で YOLOv4 による物体検出](https://qiita.com/futakuchi0117/items/c26ade963d2e79d3f9cc)
Makefile をJetson用に変更する手順が書かれている。これは[YoloV4のオリジナルの実装](https://github.com/AlexeyAB/darknet)をJetsonで実行している例だ。

```
$ ./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg
```

Jetson Xavier NX では「FPSは11.0～12.0程度でした．Jetson nanoでは1～2FPS程度でしたので，かなり速くなりましたね．」

### youtube[yolov4 with tensorRT FP16 on jetson NX] (https://www.youtube.com/watch?v=Mw0yQA6yrGw)

<iframe width="560" height="315" src="https://www.youtube.com/embed/Mw0yQA6yrGw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### YouTube [Nvidia Jetson (AGX) Xavier - YOLOv4 REALTIME Detection Test](https://www.youtube.com/watch?v=futAjvo1VbI)

<iframe width="560" height="315" src="https://www.youtube.com/embed/futAjvo1VbI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

これも、オリジナルのYoloV4の実装からビルドして実行している例のようだ。

### [YOLOv4-tiny neural network to detect flames](https://www.youtube.com/watch?v=NqSvnIHe2Sc)

これは、火災の炎を検出する動画。YoloV4の枠組みを使って学習しているもののようだ。

### 他の実装、object detection はYolo以外もある。
それぞれのプラットフォームで、チュートリアルがあって提供している学習済みモデルは気にしよう。
そのプラットフォームでの利用において、何らかの強みがある理由があって公開していることがあるからだ。
(darknetのYoloの実装では、複数のカメラ入力に対して、1台のマシンで同時に推論することを実演できないでしょう。でも、各プラットフォームのチュートリアルに用意されているサンプルでは、複数の処理を同時にどれくらいできるのかを示している。)

https://github.com/dusty-nv/jetson-inference#locating-object-coordinates-using-detectnet

----
## pytorch

### https://github.com/Tianxiaomo/pytorch-YOLOv4
> ONNX and TensorRT models are converted from Pytorch 
とあるので、NVIDIA のデバイスでTensorRTを使って高速化することができる。

### https://github.com/maudzung/Complex-YOLOv4-Pytorch

![](https://raw.githubusercontent.com/maudzung/Complex-YOLOv4-Pytorch/master/docs/complex_yolo_architecture.PNG)

> Realtime 3D object detection based on YOLOv4
とあり、矩形ではなく、直方体に相当する位置の検出を行なっている。

https://github.com/WongKinYiu/PyTorch_YOLOv4

## これもpytorch のyolov4の実装
https://github.com/ultralytics/yolov3/blob/master/cfg/yolov4.cfg　(リンク切れ)

ここには、次のリポジトリが公開されている。
https://github.com/ultralytics/yolov5
https://github.com/ultralytics/xview-yolov3


## Keras
### https://github.com/Ma-Dan/keras-yolo4
> Convert the Darknet YOLOv4 model to a Keras model.

この実装は、学習済みモデルをkerasに変換して実行するための環境のようだ。

https://github.com/miemie2013/Keras-YOLOv4


## [TF Keras YOLOv4/v3/v2 Modelset](https://github.com/david8862/keras-YOLOv3-model-set)

ここでも、Yoloの各種の実装のｍAPの値が示されている。


## tensorflow-yolov4
https://pypi.org/project/yolov4/

この実装は次のようにpip でインストールできる。

```
$ pip install yolov4
```

[tensorflow-yolov4 Docs](
https://wiki.loliot.net/docs/lang/python/libraries/yolov4/python-yolov4-about/) にその解説が書いてある。

[そこに書いてある推論のスクリプト例](https://wiki.loliot.net/docs/lang/python/libraries/yolov4/python-yolov4-about/#tensorflow )を引用する。


```
from yolov4.tf import YOLOv4

yolo = YOLOv4()
# yolo = YOLOv4(tiny=True)

yolo.classes = "coco.names"
yolo.input_size = (640, 480)

yolo.make_model()
yolo.load_weights("yolov4.weights", weights_type="yolo")
# yolo.load_weights("yolov4-tiny.weights", weights_type="yolo")

yolo.inference(media_path="kite.jpg")

yolo.inference(media_path="road.mp4", is_image=False)
```

## tensorflow-lite-yolov4

### https://github.com/hunglc007/tensorflow-yolov4-tflite

>The training performance is not fully reproduced yet, so I recommended to use Alex's Darknet to train your own data, then convert the .weights to tensorflow or tflite.
やはり、tensorflow lite は学習用の環境ではない。学習済みのモデルをtensorflow lite に変換するとよいようだ。
tensorRTに変換することができる。


https://github.com/AllanYiin/YoloV4#yolo-v4-for-pytorch--tensorflow-eager-mode-and-onnx-by-trident-api

## onnx
Onnx は、フレームワーク間において相互運用を可能にする為の取り組みとして、期待されているプラットフォームである。そのため、ONNXモデルを介して、他のプラットフォームへの変換の道筋が増やされてきている。
onnx ファイルは onnxruntime を使って推論をさせることもできる。


https://github.com/onnx/models/tree/master/vision/object_detection_segmentation/yolov4

## openvino
OpenVinoはIntelの各種デバイスでの推論を実行するための枠組みです。
他のプラットフォームで学習した結果を、Intelのデバイスで実行するための枠組みですから、OpenVinoの枠組みでは学習をすることができません。

https://github.com/TNTWEN/OpenVINO-YOLOV4
https://twitter.com/UnaNancyOwen/status/1284048478126014464
> YoloV4-tiny の OpenVINO モデル FP32/FP16 を生成してコミットしました。 x86 CPU only で 416x416 = 52.33 FPS、 256x256 = 130.86 FPS でした。 異常に速いですね

https://github.com/PINTO0309/PINTO_model_zoo/tree/master/031_yolov4

https://docs.openvinotoolkit.org/latest/omz_models_model_yolo_v4_tf.html

## tensorRT

https://github.com/jkjung-avt/tensorrt_demos#demo-5-yolov4
JetsonNano でのさまざまなyoloモデルでのｆｐｓが示されている。

![Screenshot from 2020-09-29 01-15-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/307fc6e8-7d5f-cb91-fd8e-3660911df464.png)

>Download the pre-trained yolov3/yolov4 COCO models and convert the targeted model to ONNX and then to TensorRT engine. 

「事前にトレーニングされたyolov3 / yolov4 COCOモデルをダウンロードし、ターゲットモデルをONNXに変換してから、TensorRTエンジンに変換します」

TensorRT は、推論用のフレームワークなので、学習は別のフレームワークで行った結果をTensorRTに変換している。

変換例：
onnx ファイルから tensorRT ファイル。
(例えばfp16などモデルの型を指定する。)

fp16ならば、変換元の重みファイルだけでtensorRT ファイルに変換ができる。
（int8に変換する場合には、重みファイルだけではなく、重みの値の領域を決めるための入力データが必要になる。）


Youtube [Increase YOLOv4 object detection speed on GPU with TensorRT](https://www.youtube.com/watch?v=Gd-9cUb7x5Q)

<iframe width="560" height="315" src="https://www.youtube.com/embed/Gd-9cUb7x5Q" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## NVIDIAの公式のgithub にあるYolov4
https://github.com/NVIDIA-AI-IOT/yolov4_deepstream
以下の２つがある。

- tensorrt_yolov4
- deepstream_yolov4
NVIDIAのGPU環境でTensorRTを使う前提ならば、このリポジトリが使えそうだ。



## Xilinx
YOLOv4 Tutorials
https://github.com/Xilinx/Vitis-Tutorials/blob/master/Machine_Learning/Design_Tutorials/07-yolov4-tutorial/README.md

## Google Coral TPU
https://wiki.loliot.net/docs/lang/python/libraries/yolov4/python-yolov4-edge-tpu/
---
Youtube [Yolo V4 - How it Works & Why it's So Amazing!](https://www.youtube.com/watch?v=_JzOFWx1vZg)

### 付記：システム構成で気にかけること
- 深層学習が処理のパフォーマンスが得られやすい使い方とそうでない使い方がある。
- 処理のパフォーマンスが得られやすい使い方：
    - 複数のカメラ入力を 　同一のバッチにまとめて推論をする。
- 処理のパフォーマンスが得られない使い方：
    - 複数のカメラ入力ごとに推論を実行する。

メモリ管理にCPUの負荷が高くなると、他のデバイスでの処理が速くても、他のデバイスに処理を外だしする利点が得られにくくなる。

- 動画のストリームをどう管理するかが必要になる。
- たいがいの場合、深層学習で検出した結果だけが必要になるのではなくて、どのフレームの中のどの位置で、検出しているのか、元の画像中に検出結果を表示する必要がある。
- カメラから取得される動画像を、どのように受け取り、深層学習で検出し、結果をどう送信するのか。

## 追記
検出アルゴリズムは、追跡アルゴリズムとセットになって使うことがとても多い。
yolov4と追跡アルゴリズムがセットになった実装をさぐることにしようと思う。
[DeepSort とYolov4の組み合わせの実装を調査中](https://qiita.com/nonbiri15/items/54949e179302353deea5)