# YOLOv9
## 论文
- https://arxiv.org/abs/2402.13616
## 模型结构
YOLOv9将可编程梯度信息 (PGI) 概念与通用 ELAN (GELAN)架构相结合而开发，代表了准确性、速度和效率方面的重大飞跃。

<div align=center>
    <img src="./doc/yolov9-model.png"/>
</div>

## 算法原理
Yolov9将可编程梯度信息（PGI）和GLEAN（用于对象检测的生成潜在嵌入）架构集成到YOLOv9中可以增强其在对象检测任务中的性能。可编程梯度信息（PGI）概念，有助于通过辅助可逆分支生成可靠的梯度。这确保深度特征保留执行目标任务所需的关键特征，解决深度神经网络前馈过程中信息丢失的问题。通用ELAN（GELAN）架构，旨在优化参数、计算复杂度、准确性和推理速度。通过允许用户为不同的推理设备选择合适的计算模块，GELAN 增强了 YOLOv9 的灵活性和效率。实验结果表明，YOLOv9 在 MS COCO 等基准数据集上的目标检测任务中实现了最佳性能。它在准确性、速度和整体性能方面超越了现有的实时物体检测器，使其成为需要物体检测功能的各种应用的最先进的解决方案。

<div align=center>
    <img src="./doc/pgi.png"/>
</div>
PGI主要包括主分支, 辅助可逆分支, 多级辅助信息三个组成部分。PGI推理过程仅使用主分支，因此不需要任何额外的推理成本。

<div align=center>
    <img src="./doc/gelan.png"/>
</div>

YOLOv9提出了新网络架构——GELAN。GELAN通过结合两种神经网络架构，即结合用梯度路径规划（CSPNet）和（ELAN）设计了一种广义的高效层聚合网络（GELAN）；GELAN综合考虑了轻量级、推理速度和准确度。GELAN整体架构如上图所示。YOLOv9将ELAN的能力进行了泛化，原始ELAN仅使用卷积层的堆叠，而GELAN可以使用任何计算块作为基础Module。

## 环境配置
### Docker（方法一）
从[光源](https://www.sourcefind.cn/#/service-list)中拉取docker镜像：
```
docker pull image.sourcefind.cn:5000/dcu/admin/base/pytorch:1.13.1-centos7.6-dtk23.10-py310
```
创建容器并挂载目录进行开发：
```
docker run -it --name {name} --shm-size=1024G  --device=/dev/kfd --device=/dev/dri/ --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --ulimit memlock=-1:-1 --ipc=host --network host --group-add video -v /parastor/DL_DATA:/home/data:ro -v /public/DL_DATA:/home/data2:ro -v /opt/hyhal:/opt/hyhal:ro -v /parastor/home/:/home/ {docker_image} /bin/bash
# 修改1 {name} 需要改为自定义名称，建议命名{框架_dtk版本_使用者姓名},如果有特殊用途可在命名框架前添加命名
# 修改2 {docker_image} 需要需要创建容器的对应镜像名称，如: pytorch:1.10.0-centos7.6-dtk-23.04-py37-latest【镜像名称:tag名称】
# 修改3 -v 挂载路径到容器指定路径
```
### Dockerfile（方法二）
```
docker build --no-cache -t yolov9_pytorch:1.0 .
docker run -it --name {name} --shm-size=1024G  --device=/dev/kfd --device=/dev/dri/ --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --ulimit memlock=-1:-1 --ipc=host --network host --group-add video -v /parastor/DL_DATA:/home/data:ro -v /public/DL_DATA:/home/data2:ro -v /opt/hyhal:/opt/hyhal:ro -v /parastor/home/:/home/ {docker_image} /bin/bash
```
### Anaconda（方法三）
线上节点推荐使用conda进行环境配置。
创建python=3.10的conda环境
```
conda create -n yolov9 python=3.10
```

关于本项目DCU显卡所需的特殊深度学习库可从[光合](https://developer.hpccube.com/tool/)开发者社区下载安装。
```
DTK驱动：dtk23.10
python：python3.10
pytorch:1.13.1
```
`Tips：以上dtk驱动、python、paddle等DCU相关工具版本需要严格一一对应`

其它非深度学习库参照requirements.txt安装：
```
pip install -r requirements.txt
```
## 数据集
`MS COCO`

- 训练集[train2017.zip](http://images.cocodataset.org/zips/train2017.zip)，验证集[val2017.zip](http://images.cocodataset.org/zips/val2017.zip)，以及标签[label](https://github.com/WongKinYiu/yolov7/releases/download/v0.1/coco2017labels-segments.zip)
创建空文件夹datasets，将标签文件进行解压后放入datasets，然后将训练集和验证集分别解压后放入datasets/coco/images文件夹中。
训练数据目录结构如下：
```
 ── coco
    |   ├── images
    |             ├── train2017
    |                          ├── xxx.png
    |                          ├── xxx.png
    |                          └── xxx.png
    |             ├── val2017
    |                          ├── xxx.png
    |                          ├── xxx.png
    |                          └── xxx.png
    |   ├── labels  
    |             ├── train2017
    |                          ├── xxx.txt
    |                          ├── xxx.txt
    |                          └── xxx.txt
    |             ├── val2017
    |                          ├── xxx.txt
    |                          ├── xxx.txt
    |                          └── xxx.txt
    |   train2017.txt
    |   val2017.txt
```
- 项目中已提供用于试验训练的迷你训练数据集[train2017.zip](https://pan.baidu.com/s/1g7UIedXrOkqglRAg1AFRxw?pwd=mmf6)(mmf6),对应标签[train2017.txt](https://pan.baidu.com/s/1KzoP-T4-dtdrs42U05_CcQ?pwd=r2kk)(r2kk)，将训练集放入datasets/coco/images中，将train2017.txt放入datasets/coco中。
## 训练
权重文件下载[yolov9-c.pt](https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt)
### 单机多卡
```
python -m torch.distributed.launch --nproc_per_node 8 --master_port 9527 train_dual.py --workers 8 --device 0,1,2,3,4,5,6,7 --sync-bn --batch 128 --data data/coco.yaml --img 640 --cfg models/detect/yolov9-c.yaml --weights yolov9-c.pt --name yolov9-c --hyp hyp.scratch-high.yaml --min-items 0 --epochs 500 --close-mosaic 15
```

### 单机单卡
```
python train_dual.py --workers 8 --device 0 --batch 16 --data data/coco.yaml --img 640 --cfg models/detect/yolov9-c.yaml --weights yolov9-c.pt --name yolov9-c --hyp hyp.scratch-high.yaml --min-items 0 --epochs 500 --close-mosaic 15
```
## 推理
使用权重文件[yolov9-c.pt](https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt)，运行yolov9推理
```
python detect_dual.py --source './data/images/horses.jpg' --img 640 --device 0 --weights './yolov9-c.pt' --name yolov9_c_640_detect
```
## result

<div align=center>
    <img src="./doc/horses_prediction.jpg"/>
</div>

### 精度
测试数据：[test](http://images.cocodataset.org/zips/test2017.zip)

测试指标：
```
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.530
 Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.703
 Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.578
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.363
 Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.585
 Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.691
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.392
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.651
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.700
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.539
 Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.759
 Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.847
```
## 应用场景
### 算法类别
目标检测、目标分割

### 热点应用行业
安防、交通、教育


## 源码仓库及问题反馈
[https://developer.hpccube.com/codes/modelzoo/yolov9_pytorch](https://developer.hpccube.com/codes/modelzoo/yolov9_pytorch)
## 参考资料
[https://github.com/WongKinYiu/yolov9](https://github.com/WongKinYiu/yolov9)


