MMRotate v0.3.4实战:从DOTA数据集到自定义数据集的完整训练流程(附避坑指南)
MMRotate v0.3.4实战:从DOTA数据集到自定义数据集的完整训练流程(附避坑指南)
旋转目标检测技术在遥感图像分析、自动驾驶等领域具有广泛应用价值。MMRotate作为OpenMMLab生态中的旋转目标检测工具箱,其v0.3.4版本在模型性能和易用性方面都有显著提升。本文将深入探讨如何将公开数据集DOTA的处理经验迁移到自定义数据集训练中,解决实际工程落地中的关键问题。
1. 环境配置与工具准备
1.1 基础环境搭建
推荐使用conda创建隔离的Python环境以避免依赖冲突:
conda create -n mmrotate python=3.8 -y conda activate mmrotate对于PyTorch的安装,需特别注意CUDA版本与显卡驱动的兼容性。以NVIDIA 30系列显卡为例:
pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 -f https://download.pytorch.org/whl/torch_stable.htmlMMRotate的依赖安装建议使用MIM工具链:
pip install -U openmim mim install mmcv-full mim install "mmdet<3.0.0" git clone https://github.com/open-mmlab/mmrotate.git cd mmrotate pip install -v -e .注意:
pip install -v -e .命令末尾的点号不可省略,这是将当前目录以可编辑模式安装的关键
1.2 标注工具选择
对于旋转框标注,推荐以下两种方案:
| 工具名称 | 适用场景 | 输出格式 | 安装方式 |
|---|---|---|---|
| roLabelImg | 桌面端标注 | XML/Pascal VOC | pip install roLabelImg |
| CVAT | 团队协作/在线标注 | COCO/DOTA | Docker容器部署 |
roLabelImg的常用快捷键:
W:创建旋转矩形Ctrl+S:保存当前标注→:下一张图像
2. 数据准备与格式转换
2.1 DOTA数据集预处理
DOTA数据集的标准目录结构应如下:
DOTA/ ├── train/ │ ├── images/ │ └── labelTxt/ ├── val/ │ ├── images/ │ └── labelTxt/ └── test/ ├── images/ └── labelTxt/由于DOTA图像尺寸较大(通常4000×4000像素),需要进行切片处理:
# 单尺度切片示例 python tools/data/dota/split/img_split.py \ --base-json tools/data/dota/split_configs/ss_train.json \ --save-dir splits/train关键参数说明:
patch_size: 切片尺寸(默认1024)gap: 切片重叠区域(建议200像素)rates: 多尺度切片的缩放比例
2.2 自定义数据集转换
常见标注格式转换流程:
- VOC转DOTA格式:
def voc_to_dota(xml_file, txt_file): tree = ET.parse(xml_file) root = tree.getroot() with open(txt_file, 'w') as f: for obj in root.findall('object'): robndbox = obj.find('robndbox') # 坐标转换逻辑... f.write(f"{x1} {y1} {x2} {y2} {x3} {y3} {x4} {y4} {class_name} {difficulty}\n")COCO转DOTA格式: 需特别注意旋转角度的表示差异,COCO使用
[x,y,w,h,θ]而DOTA需要四个角点坐标。数据集划分脚本:
from sklearn.model_selection import train_test_split img_files = glob.glob('images/*.jpg') train, val = train_test_split(img_files, test_size=0.2, random_state=42)3. 配置文件深度定制
3.1 数据集配置调整
修改configs/_base_/datasets/dotav1.py:
data = dict( samples_per_gpu=4, # 根据GPU显存调整 workers_per_gpu=2, # 推荐为CPU核心数的1/4 train=dict( type='DOTADataset', ann_file='data/custom/train/annfiles/', img_prefix='data/custom/train/images/'), val=dict( type='DOTADataset', ann_file='data/custom/val/annfiles/', img_prefix='data/custom/val/images/'), test=dict( type='DOTADataset', ann_file='data/custom/test/annfiles/', img_prefix='data/custom/test/images/'))3.2 模型配置优化
以R3Det模型为例,关键修改点:
- 类别数调整:
model = dict( bbox_head=dict( num_classes=10)) # 修改为自定义类别数- 预训练权重加载:
load_from = 'checkpoints/r3det_r50_fpn_1x_dota-3c2215c4.pth'- 学习率策略:
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001) lr_config = dict( policy='CosineAnnealing', warmup='linear', warmup_iters=1000, warmup_ratio=1.0/3, min_lr_ratio=1e-5)4. 训练与调优实战
4.1 分布式训练启动
单GPU训练:
python tools/train.py configs/r3det/r3det_r50_fpn_1x_dota.py --work-dir work_dirs/custom多GPU训练(4卡示例):
./tools/dist_train.sh configs/r3det/r3det_r50_fpn_1x_dota.py 4 --work-dir work_dirs/custom4.2 常见问题排查
- 显存不足:
- 减小
samples_per_gpu - 使用梯度累积:
optimizer_config = dict( grad_clip=dict(max_norm=35, norm_type=2), cumulative_iters=4) # 每4次迭代更新一次权重- 训练震荡:
- 增加
warmup_iters - 尝试
SyncBN:
norm_cfg = dict(type='SyncBN', requires_grad=True)- 验证指标异常:
- 检查标注文件编码(必须UTF-8)
- 确认
class_names顺序与标注一致
4.3 模型测试与部署
推理演示:
python demo/image_demo.py \ demo/demo.jpg \ configs/r3det/r3det_r50_fpn_1x_dota.py \ work_dirs/custom/latest.pth \ --out-file result.jpg模型导出为ONNX格式:
from mmdeploy.apis import export_model export_model( 'configs/r3det/r3det_r50_fpn_1x_dota.py', 'work_dirs/custom/latest.pth', 'demo/demo.jpg', 'output', backend='onnxruntime')在实际项目中,我们发现以下配置组合效果较好:
- 使用
RotatedIoULoss代替SmoothL1Loss - 数据增强中加入
RandomRotate90 - 对于小目标检测,将
anchor_scales调整为[2, 4, 8]
