MMYOLO实战:5步搞定YOLOv8训练自定义VOC数据集(附完整代码)
MMYOLO实战:5步高效训练YOLOv8自定义VOC数据集
在计算机视觉领域,目标检测一直是核心技术之一。YOLO系列算法以其高效的检测速度和良好的精度表现,成为工业界和学术界的热门选择。而MMYOLO作为商汤科技基于PyTorch框架开发的开源工具箱,集成了YOLOv5到YOLOv8等多个版本算法,为开发者提供了统一、高效的训练和推理平台。本文将手把手带你完成从VOC数据集准备到YOLOv8模型训练的全流程,特别针对数据格式转换这一关键痛点提供详细解决方案。
1. 环境配置与MMYOLO安装
搭建正确的开发环境是项目成功的第一步。MMYOLO对Python和PyTorch版本有一定要求,建议使用conda创建独立环境以避免依赖冲突。
conda create -n mmyolo python=3.8 -y conda activate mmyolo对于GPU用户,安装对应版本的PyTorch和TorchVision:
conda install pytorch torchvision cudatoolkit=11.3 -c pytorch接下来克隆MMYOLO仓库并安装依赖:
git clone https://github.com/open-mmlab/mmyolo.git cd mmyolo pip install -U openmim mim install -r requirements/mminstall.txt mim install -r requirements/albu.txt mim install -v -e .提示:使用
-e参数以可编辑模式安装,这样对代码的本地修改会立即生效,无需重新安装。
验证安装是否成功:
import mmyolo print(mmyolo.__version__)若成功输出版本号,则说明环境配置完成。接下来我们需要准备数据集。
2. VOC数据集转换与处理
VOC格式是目标检测领域常用的数据集格式,但MMYOLO训练需要COCO格式的标注文件。我们需要将VOC转换为中间格式再转为COCO格式。
2.1 VOC转LabelMe格式
VOC数据集通常具有以下目录结构:
VOCdevkit/ └── VOC2007/ ├── Annotations/ # XML标注文件 ├── JPEGImages/ # 图像文件 ├── ImageSets/ # 数据集划分信息我们首先将VOC转换为LabelMe格式,以下是完整的转换脚本:
import os import glob import json import shutil import xml.etree.ElementTree as ET from PIL import Image def parse_voc_xml(xml_path): tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') width = int(size.find('width').text) height = int(size.find('height').text) objects = [] for obj in root.iter('object'): cls = obj.find('name').text bndbox = obj.find('bndbox') xmin = float(bndbox.find('xmin').text) ymin = float(bndbox.find('ymin').text) xmax = float(bndbox.find('xmax').text) ymax = float(bndbox.find('ymax').text) objects.append({ 'label': cls, 'points': [[xmin, ymin], [xmax, ymax]], 'shape_type': 'rectangle' }) return objects, width, height def voc_to_labelme(voc_dir, output_dir): if not os.path.exists(output_dir): os.makedirs(output_dir) xml_dir = os.path.join(voc_dir, 'Annotations') img_dir = os.path.join(voc_dir, 'JPEGImages') for xml_file in glob.glob(os.path.join(xml_dir, '*.xml')): base_name = os.path.basename(xml_file).split('.')[0] img_file = os.path.join(img_dir, base_name + '.jpg') objects, width, height = parse_voc_xml(xml_file) labelme_data = { 'version': '5.1.1', 'flags': {}, 'shapes': objects, 'imagePath': os.path.basename(img_file), 'imageData': None, 'imageHeight': height, 'imageWidth': width } # 复制图片到输出目录 shutil.copy(img_file, output_dir) # 保存LabelMe格式的JSON文件 with open(os.path.join(output_dir, base_name + '.json'), 'w') as f: json.dump(labelme_data, f, indent=2) # 使用示例 voc_to_labelme('VOCdevkit/VOC2007', 'labelme_dataset')2.2 LabelMe转COCO格式
获得LabelMe格式数据后,使用MMYOLO提供的工具转换为COCO格式:
python tools/dataset_converters/labelme2coco.py \ --img-dir labelme_dataset \ --labels-dir labelme_dataset \ --out coco_annotations.json转换完成后,建议检查COCO标注是否正确:
python tools/analysis_tools/browse_coco_json.py \ --img-dir labelme_dataset \ --ann-file coco_annotations.json3. 数据集划分与配置
3.1 数据集划分
将数据集划分为训练集、验证集和测试集:
python tools/misc/coco_split.py \ --json coco_annotations.json \ --out-dir split_dataset \ --ratios 0.7 0.2 0.1 \ --shuffle这将生成三个JSON文件:
split_dataset/train.jsonsplit_dataset/val.jsonsplit_dataset/test.json
3.2 配置文件修改
MMYOLO使用配置文件控制训练过程。我们可以基于现有配置进行修改。以YOLOv8为例,复制默认配置文件:
cp configs/yolov8/yolov8_s_syncbn_fast_8xb16-500e_coco.py configs/custom_dataset/yolov8_s_custom.py需要修改的主要部分包括:
- 数据集配置:
data_root = 'split_dataset/' train_ann_file = 'train.json' train_data_prefix = '' # 图像路径前缀 val_ann_file = 'val.json' val_data_prefix = ''- 类别信息:
metainfo = { 'classes': ('cat', 'dog', 'person'), # 替换为你的类别 'palette': [ (220, 20, 60), (119, 11, 32), (0, 0, 142) ] }- 训练参数调整:
train_cfg = dict( max_epochs=100, # 训练轮数 val_interval=5) # 验证间隔4. 数据增强与模型训练
4.1 数据增强策略
MMYOLO提供了丰富的数据增强选项,可以在配置文件中调整:
train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations'), dict( type='RandomResize', scale=(640, 640), ratio_range=(0.5, 2.0), keep_ratio=True), dict(type='RandomFlip', prob=0.5), dict(type='PhotoMetricDistortion'), dict(type='PackDetInputs') ]4.2 开始训练
使用以下命令启动训练:
python tools/train.py configs/custom_dataset/yolov8_s_custom.py训练过程中可以监控关键指标:
| 指标名称 | 说明 | 正常范围 |
|---|---|---|
| loss_cls | 分类损失 | 逐渐下降 |
| loss_bbox | 边界框回归损失 | 逐渐下降 |
| mAP | 平均精度 | 逐渐上升 |
注意:训练初期指标波动较大是正常现象,随着训练进行应趋于稳定。
5. 模型评估与推理
5.1 模型评估
训练完成后,使用验证集评估模型性能:
python tools/test.py \ configs/custom_dataset/yolov8_s_custom.py \ work_dirs/yolov8_s_custom/epoch_100.pth \ --show-dir results/5.2 单张图像推理
MMYOLO提供了方便的推理接口:
from mmdet.apis import init_detector, inference_detector config_file = 'configs/custom_dataset/yolov8_s_custom.py' checkpoint_file = 'work_dirs/yolov8_s_custom/epoch_100.pth' model = init_detector(config_file, checkpoint_file, device='cuda:0') result = inference_detector(model, 'test_image.jpg') model.show_result('test_image.jpg', result, out_file='result.jpg')5.3 批量推理
对于大量图像,可以使用以下脚本:
import os from mmdet.apis import init_detector, inference_detector config_file = 'configs/custom_dataset/yolov8_s_custom.py' checkpoint_file = 'work_dirs/yolov8_s_custom/epoch_100.pth' model = init_detector(config_file, checkpoint_file, device='cuda:0') input_dir = 'test_images/' output_dir = 'results/' os.makedirs(output_dir, exist_ok=True) for img_name in os.listdir(input_dir): img_path = os.path.join(input_dir, img_name) result = inference_detector(model, img_path) model.show_result( img_path, result, out_file=os.path.join(output_dir, img_name) )在实际项目中,YOLOv8在自定义数据集上的表现往往取决于数据质量和训练策略。通过合理调整学习率、数据增强和模型结构,我们可以在保持实时性的同时获得不错的检测精度。
