配置环境
创建 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.py
和 yolov5_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 模型
环境依赖
参考官方文档
pip install onnx
- onnx-simplifier (可选,用于简化模型)
pip install onnx-simplifier
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 目录下的相对目录中执行,请修改对应目录。
参考文章:
- 模型精度评测(Evaluation) — mmengine 0.10.5 文档
- 一文解决mmcv安装过程中的版本问题!!!_mmcv版本-优快云博客
- 标注+训练+测试+部署全流程 — MMYOLO 0.6.0 文档
- 测试时增强相关说明 — MMYOLO 0.6.0 文档
- mmyolo/docs/zh_cn/tutorials/config.md at main · open-mmlab/mmyolo
- precision and recall · Issue #546 · open-mmlab/mmyolo
- Merge the preprocess step into the easydeploy onnx/tensorrt model by chenxinfeng4 · Pull Request #742 · open-mmlab/mmyolo
- YOLO-World/deploy/easydeploy/docs/model_convert.md at master · AILab-CVC/YOLO-World
- 使用MMYOLO中yolov8训练自己VOC数据集实战_mmyolo v8-优快云博客
- mmyolo标注+训练+测试+部署全流程_mmyolo部署-优快云博客