![license](https://img.shields.io/github/license/hhk7734/tensorflow-yolov4)
![pypi](https://img.shields.io/pypi/v/yolov4)
![language](https://img.shields.io/github/languages/top/hhk7734/tensorflow-yolov4)

# tensorflow-yolov4

YOLOv4 Implemented in Tensorflow 2.0.
Convert YOLO v4, YOLOv3, YOLO tiny .weights to .pb, .tflite and trt format for tensorflow, tensorflow lite, tensorRT.

Download yolov4.weights file: https://drive.google.com/open?id=1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT

### Prerequisites

- Tensorflow 2.1.0
- tensorflow_addons 0.9.1 (required for mish activation)

### Performance

<p align="center"><img src="data/performance.png" width="640"\></p>

### Demo

```bash
# yolov4
python detect.py --weights ./data/yolov4.weights --framework tf --size 608 --image ./data/kite.jpg

# yolov4 tflite
python detect.py --weights ./data/yolov4-int8.tflite --framework tflite --size 416 --image ./data/kite.jpg
```

#### Output

##### Yolov4 original weight

<p align="center"><img src="result.png" width="640"\></p>

##### Yolov4 tflite int8

<p align="center"><img src="result-int8.png" width="640"\></p>

### Convert to tflite

```bash
# yolov4
python convert_tflite.py --weights ./data/yolov4.weights --output ./data/yolov4.tflite

# yolov4 quantize float16
python convert_tflite.py --weights ./data/yolov4.weights --output ./data/yolov4-fp16.tflite --quantize_mode float16

# yolov4 quantize int8
python convert_tflite.py --weights ./data/yolov4.weights --output ./data/yolov4-fp16.tflite --quantize_mode full_int8 --dataset ./coco_dataset/coco/val207.txt
```

### Convert to TensorRT

```bash
# yolov3
python save_model.py --weights ./data/yolov3.weights --output ./checkpoints/yolov3.tf --input_size 416 --model yolov3
python convert_trt.py --weights ./checkpoints/yolov3.tf --quantize_mode float16 --output ./checkpoints/yolov3-trt-fp16-416

# yolov3-tiny
python save_model.py --weights ./data/yolov3-tiny.weights --output ./checkpoints/yolov3-tiny.tf --input_size 416 --tiny
python convert_trt.py --weights ./checkpoints/yolov3-tiny.tf --quantize_mode float16 --output ./checkpoints/yolov3-tiny-trt-fp16-416

# yolov4
python save_model.py --weights ./data/yolov4.weights --output ./checkpoints/yolov4.tf --input_size 416 --model yolov4
python convert_trt.py --weights ./checkpoints/yolov4.tf --quantize_mode float16 --output ./checkpoints/yolov4-trt-fp16-416
```

### Evaluate on COCO 2017 Dataset

```bash
# run script in /script/get_coco_dataset_2017.sh to download COCO 2017 Dataset
# preprocess coco dataset
cd data
mkdir dataset
cd ..
cd scripts
python coco_convert.py --input ./coco/annotations/instances_val2017.json --output val2017.pkl
python coco_annotation.py --coco_path ./coco
cd ..

# evaluate yolov4 model
python evaluate.py --weights ./data/yolov4.weights
cd mAP/extra
python remove_space.py
cd ..
python main.py --output results_yolov4_tf
```

#### mAP50 on COCO 2017 Dataset

| Detection | 512x512 | 416x416 | 320x320 |
| --------- | ------- | ------- | ------- |
| YoloV3    | 55.43   | 52.32   |         |
| YoloV4    | 61.96   | 57.33   |         |

### Benchmark

```bash
python benchmarks.py --size 416 --model yolov4 --weights ./data/yolov4.weights
```

#### TensorRT performance

| YoloV4 416 images/s | FP32 | FP16 | INT8 |
| ------------------- | ---- | ---- | ---- |
| Batch size 1        | 55   | 116  |      |
| Batch size 8        | 70   | 152  |      |

#### Tesla P100

| Detection  | 512x512 | 416x416 | 320x320 |
| ---------- | ------- | ------- | ------- |
| YoloV3 FPS | 40.6    | 49.4    | 61.3    |
| YoloV4 FPS | 33.4    | 41.7    | 50.0    |

#### Tesla K80

| Detection  | 512x512 | 416x416 | 320x320 |
| ---------- | ------- | ------- | ------- |
| YoloV3 FPS | 10.8    | 12.9    | 17.6    |
| YoloV4 FPS | 9.6     | 11.7    | 16.0    |

#### Tesla T4

| Detection  | 512x512 | 416x416 | 320x320 |
| ---------- | ------- | ------- | ------- |
| YoloV3 FPS | 27.6    | 32.3    | 45.1    |
| YoloV4 FPS | 24.0    | 30.3    | 40.1    |

#### Tesla P4

| Detection  | 512x512 | 416x416 | 320x320 |
| ---------- | ------- | ------- | ------- |
| YoloV3 FPS | 20.2    | 24.2    | 31.2    |
| YoloV4 FPS | 16.2    | 20.2    | 26.5    |

#### Macbook Pro 15 (2.3GHz i7)

| Detection  | 512x512 | 416x416 | 320x320 |
| ---------- | ------- | ------- | ------- |
| YoloV3 FPS |         |         |         |
| YoloV4 FPS |         |         |         |

### Traning your own model

```bash
# Prepare your dataset
# If you want to train from scratch:
In config.py set FISRT_STAGE_EPOCHS=0
# Run script:
python train.py

# Transfer learning:
python train.py --weights ./data/yolov4.weights
```

The training performance is not fully reproduced yet, so I recommended to use Alex's [Darknet](https://github.com/AlexeyAB/darknet) to train your own data, then convert the .weights to tensorflow or tflite.

### TODO

- [x] Convert YOLOv4 to TensorRT
- [x] YOLOv4 tflite on android
- [ ] YOLOv4 tflite on ios
- [x] Training code
- [x] Update scale xy
- [ ] ciou
- [ ] Mosaic data augmentation
- [x] Mish activation
- [x] yolov4 tflite version
- [x] yolov4 in8 tflite version for mobile

### References

- YOLOv4: Optimal Speed and Accuracy of Object Detection [YOLOv4](https://arxiv.org/abs/2004.10934).
- [darknet](https://github.com/AlexeyAB/darknet)

My project is inspired by these previous fantastic YOLOv3 implementations:

- [Yolov3 tensorflow](https://github.com/YunYang1994/tensorflow-yolov3)
- [Yolov3 tf2](https://github.com/zzh8829/yolov3-tf2)
