MMYOLO训练实战

配置环境

创建 conda 虚拟环境

conda create --name mmyolo python=3.8 -y
conda activate mmyolo

安装 Pytorch

首先查看自己电脑的 CUDA 版本

nvidia-smi
# nvidia-smi
Tue Dec 17 01:31:35 2024       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.12             Driver Version: 535.104.12   CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA A800 80GB PCIe          On  | 00000000:38:00.0 Off |                    0 |
| N/A   73C    P0             251W / 300W |  70007MiB / 81920MiB |    100%      Default |
|                                         |                      |             Disabled |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
+---------------------------------------------------------------------------------------+

查看自己的 CUDA 版本,我的是 CUDA 12.2,但是装与 12.2 对应的 Torch 时,后面会出现与 mmcv 版本不匹配的问题,从而安装失败。因此,我在这里选择了 CUDA 11.7 版本的 Torch,pytorch 的下载链接在这里(PyTorch 以前版本),往下拉,选择合适的 pytorch。虽然现在已经到了 2. X 的 PyTorch,但是为了与 mmcv 匹配,这里是选择了 1.13 版本的 Torch。

conda install pytorch==1.13.0 torchvision==0.14.0 torchaudio==0.13.0 pytorch-cuda=11.7 -c pytorch -c nvidia

这里注意,其实服务器(本机)的 CUDA 版本是 12.2,但是我们可以选择比 12.2 小的版本,因为在虚拟环境中会自己再安装一个 PyTorch 版本的CUDA 版本,打印安装包为例:

conda list cuda
(mmyolo) conda list cuda
# packages in environment at /opt/conda/envs/mmyolo:
#
# Name                    Version                   Build  Channel
cuda-cudart               11.7.99                       0    nvidia
cuda-cupti                11.7.101                      0    nvidia
cuda-libraries            11.7.1                        0    nvidia
cuda-nvrtc                11.7.99                       0    nvidia
cuda-nvtx                 11.7.91                       0    nvidia
cuda-runtime              11.7.1                        0    nvidia
cuda-version              12.6                          3    nvidia
pytorch-cuda              11.7                 h778d358_5    pytorch
(mmyolo) conda list torch
# packages in environment at /opt/conda/envs/mmyolo:
#
# Name                    Version                   Build  Channel
pytorch                   1.13.0          py3.8_cuda11.7_cudnn8.5.0_0    pytorch
pytorch-cuda              11.7                 h778d358_5    pytorch
pytorch-mutex             1.0                        cuda    pytorch
torchaudio                0.13.0               py38_cu117    pytorch
torchvision               0.14.0               py38_cu117    pytorch

我们可以看到 cuda 11.7 和 torch 1.13.0 已经安装完成,下面我们测试是否安装成功

(mmyolo) python      
Python 3.8.20 (default, Oct  3 2024, 15:24:27) 
[GCC 11.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> print (torch.cuda.is_available())
True
>>> exit()

显示为 True 则表示安装成功,若显示为 False 则未安装成功,需要排查原因重新安装。

安装 mmcv

首先要安装 mim、 mmengine

pip install -U openmim
mim install mmengine

上面与官方文档一致,但是在安装 mmcv 时,需要选择合适的版本,选择版本的地址在这里(mmcv 版本),cuda 11.7, torch 1.13, mmcv 建议不要太高,最好在 2.0.0-2.1 之间。

安装命令:

pip install mmcv==2.0.0rc4 -f https://download.openmmlab.com/mmcv/dist/cu117/torch1.13/index.html

我们还需要根据官方需求,安装 mmdet,这里可直接使用命令安装

mim install mmdet

注:如果因国内安装速度限制问题,可-i 命令添加代理提高安装速度。

-i https://pypi.tuna.tsinghua.edu.cn/simple

安装 mmyolo

按照官方安装 mmyolo 的步骤,我们从源码进行安装,命令如下:

git clone https://github.com/open-mmlab/mmyolo.git
cd mmyolo
# Install albumentations
mim install -r requirements/albu.txt
# Install MMYOLO
mim install -v -e .
# "-v" 指详细说明,或更多的输出
# "-e" 表示在可编辑模式下安装项目,因此对代码所做的任何本地修改都会生效,从而无需重新安装。

接下来,我们还需要验证是否安装成功。以官方为例:

步骤 1. 我们需要下载配置文件和模型权重文件。

cd mmyolo
mim download mmyolo --config yolov5_s-v61_syncbn_fast_8xb16-300e_coco --dest .

下载将需要几秒钟或更长时间,这取决于你的网络环境。完成后,你会在当前文件夹中发现两个文件 yolov5_s-v61_syncbn_fast_8xb16-300e_coco.pyyolov5_s-v61_syncbn_fast_8xb16-300e_coco_20220918_084700-86e02187.pth

步骤 2. 推理验证

方案 1. 如果你通过源码安装的 MMYOLO,那么直接运行以下命令进行验证:

python demo/image_demo.py demo/demo.jpg \
                          yolov5_s-v61_syncbn_fast_8xb16-300e_coco.py \
                          yolov5_s-v61_syncbn_fast_8xb16-300e_coco_20220918_084700-86e02187.pth
# 可选参数
# --out-dir ./output *检测结果输出到指定目录下,默认为./output, 当--show参数存在时,不保存检测结果
# --device cuda:0    *使用的计算资源,包括cuda, cpu等,默认为cuda:0
# --show             *使用该参数表示在屏幕上显示检测结果,默认为False
# --score-thr 0.3    *置信度阈值,默认为0.3

运行结束后,在 output 文件夹中可以看到检测结果图像,图像中包含有网络预测的检测框。

![[demo.jpg]]

出现上述检测框图像则已经配置成功

数据集准备

这里数据集格式我们以 coco 格式为例,数据集文件格式如下:

└── ./dataset/DataName
    ├── images # 图片文件
    │    ├── image1.jpg
    │    ├── image2.png
    │    └── ...
    ├── labels # X-AnyLabeling 标注文件
    │    ├── image1.json
    │    ├── image2.json
    │    └── ...
    ├── annotations # 数据集划分的 COCO 文件
    │    ├── annotations_all.json # 全量数据的 COCO label 文件
    │    ├── train.json # 划分比例 80% 的数据
    │    ├── val.json 	# 划分比例 10% 的数据
    │    └── test.json 	# 划分比例 10% 的数据

本文使用 X-AnyLabeling 的标注格式 (也可以使用官方推荐的 labelme 标注)

使用脚本将 json 标注转换为 Coco 格式

命令如下:

python tools/dataset_converters/X-AnyLabeling2coco.py --img-dir ./dataset/DataName/images \  
                                                --labels-dir ./dataset/DataName/labels \  
                                                --out ./dataset/DataName/annotations/annotations_all.json
# 可选参数
# --class-id-txt ./dataset/DataName/class_with_id.txt    *所有类 id txt 路径,默认为空

脚本代码可参考官方提供的 mmyolo/tools/dataset_converters/labelme2coco.py 文件

检查转换的 COCO label 是否正确

python tools/analysis_tools/browse_coco_json.py --img-dir ./dataset/DataName/images \  
                                                --ann-file ./dataset/DataName/annotations/annotations_all.json

通过可视化查看 coco 格式是否转换正确,该脚本会将 coco 格式的标注在原图上显示。注意,服务器若没有可视化工具,则不能使用,会超时运行。

数据集划分为训练集、验证集和测试集

果数据量比较少,可以不划分验证集。下面是划分脚本的具体用法:

python tools/misc/coco_split.py --json ./dataset/DataName/annotations/annotations_all.json \  
                                --out_dir ./dataset/DataName/annotations \  
                                --ratios 0.8 0.1 0.1 \  
                                --shuffle \  
                                --seed 42
# 如果只分训练和验证集则需要将生成的trainval.json修改文件名称为train.json或者在训练文件中选择trainval.json

其中:

  • –ratios:划分的比例,如果只设置了 2 个,则划分为 trainval + test,如果设置为 3 个,则划分为 train + val + test。支持两种格式 —— 整数、小数:

    • 整数:按比例进行划分,代码中会进行归一化之后划分数据集。例子: --ratio 2 1 1(代码里面会转换成 0.5 0.25 0.25) or --ratio 3 1(代码里面会转换成 0.75 0.25)

    • 小数:划分为比例。如果加起来不为 1 ,则脚本会进行自动归一化修正。例子: --ratio 0.8 0.1 0.1 or --ratio 0.8 0.2

  • –shuffle: 是否打乱数据集再进行划分;

  • –seed:设定划分的随机种子,不设置的话自动生成随机种子。

计算 anchor

如果是 yolov7 之前版本则需要计算 anchor

python tools/analysis_tools/optimize_anchors.py ./configs/yolov7_DataName/yolov7_w_1280_720_DataName.py \  
                                                --algorithm v5-k-means \  
                                                --input-shape 1280 720 \  
                                                --prior-match-thr 4.0 \  
                                                --out-dir ./dataset/Habitat/

其中参数 --input-shape 表示的图像的尺寸,并不是模型需要输入的尺寸。

修改 config 文件(以 yolov 7 为例)

因为是我们自定义的数据集,所以我们需要自己新建一个 config 并加入需要修改的部分信息。为了不污染官方的 config 文件,我们可以在 configs 目录下新建一个新的目录 yolov7_DataName,同时在里面新建 config 文件,并添加以下内容:

└── ./configs/yolov7_DataName
	├── yolov7_w_1280_720_DataName.py

yolov7_w_1280_720_DataName.py 的内容参考官方文档

# -*- coding: utf-8 -*-  
"""  
@Project : mmyolo  
@FileName: yolov7_w_1280_720_DataName.py  
@Time    : 2024/10/23 下午5:30  
"""  
import json  
import os  
  
_base_ = '../yolov7/yolov7_w-p6_syncbn_fast_8x16b-300e_coco.py'  
  
max_epochs = 100  # 训练的最大 epoch
data_root = './dataset/Habitat/'  # 数据集目录的绝对路径  
# data_root = '/root/workspace/mmyolo/data/cat/'  # Docker 容器里面数据集目录的绝对路径  
  
# 结果保存的路径,可以省略,省略保存的文件名位于 work_dirs 下 config 同名的文件夹中  
work_dir = './work_dirs/yolov7_w_1280_720_DataName'  
  
# load_from 可以指定本地路径或者 URL,设置了 URL 会自动进行下载,因为上面已经下载过,我们这里设置本地路径
load_from = './weights/yolov7_w-p6_syncbn_fast_8x16b-300e_coco_20221123_053031-a68ef9d2.pth'  # noqa  
  
# 根据自己的 GPU 情况,修改 batch size,YOLOv5-s 默认为 8卡 x 16bstrain_batch_size_per_gpu = 16  
train_num_workers = 4  # 推荐使用 train_num_workers = nGPU x 4  
save_epoch_intervals = 2  # 每 interval 轮迭代进行一次保存一次权重  
  
# 根据自己的 GPU 情况,修改 base_lr,修改的比例是 base_lr_default * (your_bs / default_bs)=0.01 *(4/16)base_lr = _base_.base_lr / 4  
  
# TODO: anchors 修改此处已经根据数据集特点更新了 anchors,关于 anchors 的生成,使用tools/analysis_tools/optimize_anchors.py计算,并更新
anchors = [  
     [(50, 15), (68, 23), (81, 37)],  # P3/8  
     [(125, 33), (106, 56), (166, 54)],  # P4/16  
     [(165, 83), (255, 73), (238, 127)],  # P5/32  
     [(383, 121), (436, 240), (781, 215)]  # P6/64  
 ]  
  
# TODO:class修改  
class_name = ('vehicle', 'cycle', 'truck', 'bus', 'van')  # 根据 class_with_id.txt 类别信息,设置 class_name
num_classes = len(class_name)  
metainfo = dict(  
    classes=class_name,  
    palette=[(220, 20, 60), (0, 191, 255), (0, 250, 154), (255, 109, 92), (128, 64, 128), (222, 184, 135), (180, 142, 173), (153, 153, 153)]  # 画图时候的颜色,随便设置即可  
)  
  
train_cfg = dict(  
    max_epochs=max_epochs,  
    val_begin=10,  # 第几个 epoch 后验证,这里设置 20 是因为前 20 个 epoch 精度不高,测试意义不大,故跳过  
    val_interval=save_epoch_intervals  # 每 val_interval 轮迭代进行一次测试评估  
)  
  
model = dict(  
    bbox_head=dict(  
        head_module=dict(num_classes=num_classes),  
        prior_generator=dict(base_sizes=anchors),  
        # loss_cls 会根据 num_classes 动态调整,但是 num_classes = 1 的时候,loss_cls 恒为 0        loss_cls=dict(loss_weight=0.5 * (num_classes / 80 * 3 / _base_.num_det_layers))),  
    test_cfg=dict(  
        multi_label=True,  # 多分类  
        nms_pre=30000,  # nms前保留的最大检测框数量  
        score_thr=0.001,  # 过滤类别的分值3, 小于该值的会被过滤掉  
        nms=dict(type='nms', iou_threshold=0.65),  # 过滤类别的阈值,低于 0.65 的会被过滤掉  
        max_per_img=300),  # 每张图像nms后保留的最大数量  
)  
  
train_dataloader = dict(  
    batch_size=train_batch_size_per_gpu,  
    num_workers=train_num_workers,  
    dataset=dict(  
        _delete_=True,  
        type='RepeatDataset',  
        times=1,  # 数据量太少的话,可以使用 RepeatDataset ,在每个 epoch 内重复当前数据集 n 次,这里设置 5 是重复 5 次  
        dataset=dict(  
            type=_base_.dataset_type,  
            data_root=data_root,  
            metainfo=metainfo,  
            ann_file='annotations/train.json',  # 根据上述数据集划分的名称修改路径
            data_prefix=dict(img='images/'),  
            filter_cfg=dict(filter_empty_gt=False, min_size=32),  
            pipeline=_base_.train_pipeline)))  
  
val_dataloader = dict(  
    dataset=dict(  
        metainfo=metainfo,  
        data_root=data_root,  
        ann_file='annotations/val.json',  
        data_prefix=dict(img='images/')))  
  
test_dataloader = val_dataloader  
  
val_evaluator = dict(  
    type='mmdet.CocoMetric',  
    proposal_nums=(100, 1, 10,),  
    ann_file=data_root + 'annotations/val.json',  
    classwise=True,  # 设置为 True 会分别计算不同类别的 AP    # iou_thrs=[0.5, 0.75, 0.9],  # 这里的iou_thrs必须是一个list类型  
    # iou_threshold=0.2  # 设置 IoU 阈值为 0.5)  
test_evaluator = val_evaluator  
  
optim_wrapper = dict(optimizer=dict(lr=base_lr))  
  
default_hooks = dict(  
    # 设置间隔多少个 epoch 保存模型,以及保存模型最多几个,`save_best` 是另外保存最佳模型(推荐)  
    checkpoint=dict(  
        type='CheckpointHook',  
        interval=save_epoch_intervals,  
        max_keep_ckpts=3,  
        save_best='auto'),  
    param_scheduler=dict(max_epochs=max_epochs),  
    # logger 输出的间隔  
    logger=dict(type='LoggerHook', interval=10))  
# 可视化工具选择  
# visualizer = dict(vis_backends=[dict(type='LocalVisBackend'), dict(type='WandbVisBackend')])  
visualizer = dict(vis_backends=[dict(type='LocalVisBackend'), dict(type='TensorboardVisBackend')])

配置完成后,即可进行训练,命令如下:

cd /to/path/mmyolo
python tools/train.py ./configs/yolov7_DataName/yolov7_w_1280_720_DataName.py

训练完成后,对测试集进行评估

测试集评估

python tools/test.py ./configs/yolov7_DataName/yolov7_w_1280_720_DataName.py \  
                     ./work_dirs/yolov7_w_1280_720_DataName/best_coco_epoch_92.pth \  
                     --work-dir ./work_dirs/yolov7_w_1280_720_DataName/test \  
                     --out ./work_dirs/yolov7_w_1280_720_DataName/test/output.pkl \  
                     --tta \  
                     --deploy \  
                     --show-dir ./work_dirs/yolov7_w_1280_720_DataName/test/show

推理

使用官方 ./demo/image_demo.py 代码对需要推理的数据完成推理,推理结束可手工对数据进行质检用于扩充数据集或者查看推理效果。

python demo/image_demo.py ./dataset/DataName/images \
				   ./configs/yolov7_DataName/yolov7_w_1280_720_DataName.py \  
                   ./work_dirs/yolov7_w_1280_720_DataName/best_coco_epoch_92.pth \  
                   --out-dir ./result/DataName \  
                   --to-labelme \
                   --to-anylabeling
# 可选参数
# --to-labelme 		* 输出labelme格式的标注
# --to-anylabeling  * 输出X-anylabeling格式的标注,本文已经对官方代码进行更改,使其可以支持X-anylabeling格式

输出目录如下:

└── ./result/DataName
	├── images			* 效果图地址
	├── labelme			* labelme格式的标注文件地址
	├── anylabeling		* X-anylabeling格式的标注文件地址

导出onnx模型

为了方便部署,我们可以导出 onnx 模型

环境依赖

参考官方文档

  1. onnx
pip install onnx
  1. onnx-simplifier (可选,用于简化模型)
pip install onnx-simplifier
  1. onnxruntime-gpu
pip install onnxruntime-gpu==1.17.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

这里的 onnxruntime-gpu 是根据 pytorch-cuda=11.7 的版本安装的,具体可根据环境调整,如果安装 onnxruntime 则是 CPU 版本的,不能使用 GPU 完成推理。

python ./projects/easydeploy/tools/export_onnx.py \  
                ./configs/yolov7_DataName/yolov7_w_1280_720_DataName.py \  
                ./work_dirs/yolov7_w_1280_720_DataName/best_coco_epoch_92.pth \  
                --device cuda:0 \  
                --batch-size 1 \  
                --img-size 1280 1280 \  
                --opset 11 \  
                --backend onnxruntime \  
                --simplif \  
                    --pre-topk 30000 \  
                    --keep-topk 300 \  
                    --iou-threshold 0.65 \  
                    --score-threshold 0.3 \

注意这里的 --img-size 是模型输入的图像尺寸,而不是上述在训练 config 中的 --img-size 图像尺寸。

onnx推理

命令如下:

python ./projects/easydeploy/tools/image-demo.py \  
	            ./dataset/Test_images \  
	            ./work_dirs/yolov7_w_1280_720_DataName/yolov7_w_1280_720_DataName.py \  
	            ./work_dirs/yolov7_w_1280_720_DataName/best_coco_epoch_92.pth

本文的命令均在 mmyolo 目录下的相对目录中执行,请修改对应目录。

参考文章:

  1. 模型精度评测(Evaluation) — mmengine 0.10.5 文档
  2. 一文解决mmcv安装过程中的版本问题!!!_mmcv版本-优快云博客
  3. 标注+训练+测试+部署全流程 — MMYOLO 0.6.0 文档
  4. 测试时增强相关说明 — MMYOLO 0.6.0 文档
  5. mmyolo/docs/zh_cn/tutorials/config.md at main · open-mmlab/mmyolo
  6. precision and recall · Issue #546 · open-mmlab/mmyolo
  7. Merge the preprocess step into the easydeploy onnx/tensorrt model by chenxinfeng4 · Pull Request #742 · open-mmlab/mmyolo
  8. YOLO-World/deploy/easydeploy/docs/model_convert.md at master · AILab-CVC/YOLO-World
  9. 使用MMYOLO中yolov8训练自己VOC数据集实战_mmyolo v8-优快云博客
  10. mmyolo标注+训练+测试+部署全流程_mmyolo部署-优快云博客
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伪_装

您的支持,是我持续创作的光

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值