Skip to content

Commit

Permalink
docs: integration paddleyolo (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeyi-Lin authored Sep 28, 2024
1 parent ea8c511 commit bd779ce
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ function sidebarGuideCloud(): DefaultTheme.SidebarItem[] {
{ text: 'MMSegmentation', link: 'integration/integration-mmsegmentation' },
{ text: 'OpenAI', link: 'integration/integration-openai' },
{ text: 'Omegaconf', link: 'integration/integration-omegaconf' },
{ text: 'PaddleYOLO', link: 'integration/integration-paddleyolo' },
{ text: 'PyTorch', link: 'integration/integration-pytorch' },
{ text: 'PyTorch Lightning', link: 'integration/integration-pytorch-lightning' },
{ text: 'PyTorch torchtune', link: 'integration/integration-pytorch-torchtune' },
Expand Down
Binary file added assets/ig-paddleyolo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
150 changes: 150 additions & 0 deletions zh/guide_cloud/integration/integration-paddleyolo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# PaddleYolo

[PaddleYolo](https://github.com/PaddlePaddle/PaddleYOLO) 是飞桨(PaddlePaddle)框架下的一个目标检测库,主要用于图像和视频中的物体检测。PaddleYOLO包含YOLO系列模型的相关代码,支持YOLOv3、PP-YOLO、PP-YOLOv2、PP-YOLOE、PP-YOLOE+、RT-DETR、YOLOX、YOLOv5、YOLOv6、YOLOv7、YOLOv8、YOLOv5u、YOLOv7u、YOLOv6Lite、RTMDet等模型

你可以使用PaddleYolo快速进行目标检测模型训练,同时使用SwanLab进行实验跟踪与可视化。

[Demo](https://swanlab.cn/@ZeyiLin/PaddleYOLO/runs/10zy8zickn2062kubch34/chart)

## 1. 引入SwanLabCallback

首先在你clone的PaddleYolo项目中,找到`ppdet/engine/callbacks.py`文件,在代码的底部添加如下代码:

```python
class SwanLabCallback(Callback):
def __init__(self, model):
super(SwanLabCallback, self).__init__(model)

try:
import swanlab
self.swanlab = swanlab
except Exception as e:
logger.error('swanlab not found, please install swanlab. '
'Use: `pip install swanlab`.')
raise e

self.swanlab_params = {k.lstrip("swanlab_"): v for k, v in model.cfg.items() if k.startswith("swanlab_")}

self._run = None
if dist.get_world_size() < 2 or dist.get_rank() == 0:
_ = self.run
self.run.config.update(self.model.cfg)

self.best_ap = -1000.
self.fps = []

@property
def run(self):
if self._run is None:
self._run = self.swanlab.get_run() or self.swanlab.init(**self.swanlab_params)
return self._run

def on_step_end(self, status):
if dist.get_world_size() < 2 or dist.get_rank() == 0 and status['mode'] == 'train':
training_status = status['training_staus'].get()
batch_time = status['batch_time']
data_time = status['data_time']
batch_size = self.model.cfg['{}Reader'.format(status['mode'].capitalize())]['batch_size']

ips = float(batch_size) / float(batch_time.avg)
metrics = {
"train/" + k: float(v) for k, v in training_status.items()
}
metrics.update({
"train/ips": ips,
"train/data_cost": float(data_time.avg),
"train/batch_cost": float(batch_time.avg)
})

self.fps.append(ips)
self.run.log(metrics)

def on_epoch_end(self, status):
if dist.get_world_size() < 2 or dist.get_rank() == 0:
mode = status['mode']
epoch_id = status['epoch_id']

if mode == 'train':
fps = sum(self.fps) / len(self.fps)
self.fps = []

end_epoch = self.model.cfg.epoch
if (epoch_id + 1) % self.model.cfg.snapshot_epoch == 0 or epoch_id == end_epoch - 1:
save_name = str(epoch_id) if epoch_id != end_epoch - 1 else "model_final"
tags = ["latest", f"epoch_{epoch_id}"]

elif mode == 'eval':
fps = status['sample_num'] / status['cost_time']

merged_dict = {
f"eval/{key}-mAP": map_value[0]
for metric in self.model._metrics
for key, map_value in metric.get_results().items()
}
merged_dict.update({
"epoch": status["epoch_id"],
"eval/fps": fps
})

self.run.log(merged_dict)

if status.get('save_best_model'):
for metric in self.model._metrics:
map_res = metric.get_results()
key = next((k for k in ['bbox', 'keypoint', 'mask'] if k in map_res), None)

if not key:
logger.warning("Evaluation results empty, this may be due to "
"training iterations being too few or not "
"loading the correct weights.")
return

if map_res[key][0] >= self.best_ap:
self.best_ap = map_res[key][0]
save_name = 'best_model'
tags = ["best", f"epoch_{epoch_id}"]

def on_train_end(self, status):
self.run.finish()
```

## 2. 修改trainer代码

`ppdet/engine/trainer.py`文件中,在`from .callbacks import`那一行添加SwanLabCallback:

```python
from .callbacks import Callback, ComposeCallback, LogPrinter, Checkpointer, VisualDLWriter, WandbCallback, SwanLabCallback
```

接着,我们找到`Trainer`类的`__init_callbacks`方法,在`if self.mode == 'train':`下添加如下代码:

```python
if self.cfg.get('use_swanlab', False) or 'swanlab' in self.cfg:
self._callbacks.append(SwanLabCallback(self))
```

至此,你已经完成了SwanLab与PaddleYolo的集成!接下来,只需要在训练的配置文件中添加`use_swanlab: True`,即可开始可视化跟踪训练。

## 3. 修改配置文件

我们以`yolov3_mobilenet_v1_roadsign`为例。

`configs/yolov3/yolov3_mobilenet_v1_roadsign.yml`文件中,在下面添加如下代码:

```yaml
use_swanlab: true
swanlab_project: PaddleYOLO # 可选
swanlab_experiment_name: yolov3_mobilenet_v1_roadsign # 可选
swanlab_description: 对PaddleYOLO的一次训练测试 # 可选
# swanlab_workspace: swanhub # 组织名,可选
```

## 4. 开始训练

```bash
python -u tools/train.py -c configs/yolov3/yolov3_mobilenet_v1_roadsign.yml --eval
```

在训练过程中,即可看到整个训练过程的日志,以及训练结束后自动生成的可视化图表。

![paddleyolo-image](/assets/ig-paddleyolo.png)

0 comments on commit bd779ce

Please sign in to comment.