Github项目-mmdetection模型训练

Github项⽬-mmdetection模型训练
[论⽂ - MMDetection: Open MMLab Detection Toolbox and Benchmark - 2019](/abs/1906.07155)
[github open-mmlab/mmdetection](github/open-mmlab/mmdetection)
[Github 项⽬ - mmdetection ⽬标检测库 - AIUAI](www.aiuai/aifarm1216.html)
mmdetection 实现了分布式训练和⾮分布式训练,其分别使⽤的是 MMDistributedDataParallel 和 MMDataParallel .
训练过程中的所有输出,包括 log ⽂件和 checkpoints ⽂件,⾃动保存到 config 配置⽂件中的 work_dir 路径中.
1. 学习率(lr)设置
[1] - config ⽂件中的默认学习率是对于 8 GPUs 和 2 img/gpu ⽽⾔的(batchsize= 8x2=16).
[2] - 基于 Linear Scaling Rule
策略,可根据具体的 GPUs 数量和每张 GPU 的图⽚数,得到的 batchsize 的⼤⼩,以正⽐例的设置学习率,如,对于 4GPUs x
2img/gpu = 8 (batchsize),设置 lr=0.01; 对于 16GPUs x 4img/gpu = 64 (batchsize),设置 lr=0.08.
2. 单 GPU 训练
python3 tools/train.py ${CONFIG_FILE} \
--work_dir ${YOUR_WORK_DIR} #指定work_dir 路径.
3. 多 GPUs 训练
dist_train.sh:
#!/usr/bin/env bash
PYTHON=${PYTHON:-"python3"}
CONFIG=$1
GPUS=$2
$PYTHON -m torch.distributed.launch \
--nproc_per_node=$GPUS \
$(dirname "$0")/train.py $CONFIG --launcher pytorch ${@:3}
多 GPUs 训练:
./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [optional arguments]
可选参数(optional arguments) 说明:
[1] - --validate- (强烈推荐),训练过程中,每 k 个 epochs 进⾏⼀次验证(默认k=1).
[2] - --work_dir${WORK_DIR} - config⽂件中设定的⼯作路径.
[3] - --resume_from${CHECKPOINT_FILE} - 从 checkpiont ⽂件恢复训练.
[4] - resume_from 和 load_from 的区别:
resume_from 同时加载模型权重(model weights) 和优化状态(optimizer status),且 epoch 是继承了指定 checkpoint 的信息. ⼀般⽤于意外终端的训练过程的恢复.
load_from 仅加载模型权重(model weights),训练过程的 epoch 是从 0 开始训练的. ⼀般⽤于模型 finetuning.
注:
尝试了这种分布式训练,⼀直出问题,可以试试:
python3 tools/train.py configs/faster_rcnn_r50_fpn_1x.py --gpus 2 --validate
4. 多机训练
对于由 slurm
管理的集上,mmdetection 的运⾏,可以采⽤ slurm_train.sh 脚本:
slurm_train.sh :
#!/usr/bin/env bash
set -x
PARTITION=$1
JOB_NAME=$2
CONFIG=$3
WORK_DIR=$4
GPUS=${5:-8}
GPUS_PER_NODE=${GPUS_PER_NODE:-8}
CPUS_PER_TASK=${CPUS_PER_TASK:-5}
SRUN_ARGS=${SRUN_ARGS:-""}
PY_ARGS=${PY_ARGS:-"--validate"}
srun -p ${PARTITION} \
--job-name=${JOB_NAME} \
--gres=gpu:${GPUS_PER_NODE} \
-
-ntasks=${GPUS} \
--ntasks-per-node=${GPUS_PER_NODE} \
--cpus-per-task=${CPUS_PER_TASK} \
--kill-on-bad-exit=1 \
${SRUN_ARGS} \
python -u tools/train.py ${CONFIG} --work_dir=${WORK_DIR} --launcher="slurm" ${PY_ARGS}金钢绳
运⾏:
./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [${GPUS}]
例如,在 dev 分区,采⽤ 16 GPUs 训练 Mask R-CNN ⽰例:
./tools/slurm_train.sh dev mask_r50_1x configs/mask_rcnn_r50_fpn_1x.py /nfs/xxxx/mask_rcnn_r50_fpn_1x 16 5. 定制数据
对于⾃定义的数据集,最简单的⽅式是,将数据集装换为 mmdetection 中已有数据集的格式(如 COCO 和 PASCAL VOC). 5.1. COCO 数据集格式
以包含 5 个类别的定制数据集为例,假设已经被转换为 COCO 格式.
[1] - 新建 mmdet/dataset/custom_dataset.py:
from .coco import CocoDataset
from .registry import DATASETS
@ister_module
class CustomDataset(CocoDataset):
CLASSES = ('a', 'b', 'c', 'd', 'e')
[2] - 编辑 mmdet/datasets/init.py,添加:
from .custom_dataset import CustomDataset
[3] - 在 config ⽂件中即可使⽤ CustomDateset,类似于 CocoDataset.
如:
# dataset settings
dataset_type = 'CustomDataset'
data_root = 'data/custom/'
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
data = dict(
imgs_per_gpu=2,
workers_per_gpu=2,
train=dict(
type=dataset_type,
ann_file=data_root + 'annotations/custom_train.json',
img_prefix=data_root + 'custom_train/',
img_scale=(1333, 800),
img_norm_cfg=img_norm_cfg,
size_divisor=32,
flip_ratio=0.5,
with_mask=False,
with_crowd=True,
with_label=True),
38ggg
val=dict(
type=dataset_type,
ann_file=data_root + 'annotations/custom_test.json',
pm2.5监测
img_prefix=data_root + 'custom_test/',
img_scale=(1333, 800),
img_norm_cfg=img_norm_cfg,
size_divisor=32,
flip_ratio=0,
with_mask=False,
with_crowd=True,
with_label=True),
test=dict(
type=dataset_type,
ann_file=data_root + 'annotations/custom_test.json',
img_prefix=data_root + 'custom_test/',
img_scale=(1333, 800),
img_norm_cfg=img_norm_cfg,
size_divisor=32,
flip_ratio=0,
with_mask=False,
with_label=False,
test_mode=True))
5.2. ⾮ COCO 数据集格式
如果不想将定制数据集的标注数据转换为 COCO 或 PASCAL 格式,mmdetection 也是⽀持的.
mmdetection 定义了⼀个简单的标注数据格式,所有的数据集都是与之兼容的,不管是在线的还是离线的.
mmdetection 的数据标注格式为由 dict 构成的 list 格式,每个 dict 对应于⼀张图⽚.
[1] - 对于 testing,其包含 3 个 field:filename(相对路径)、width 和 height.
[2] - 对于training,其包含 4 个 field:filename(相对路径)、width 、height 和 ann. ann 也是⼀个 dict,其⾄少包含 2 个 field:boxes 和 labels,均是 numpy arrays 格式. ⼀些数据集可能会提供其它标注信息,如 crowd/difficult/ignored bboxes,⽽mmdetection 采⽤的是 bboxes_ignore 和 labels_ignore 来表⽰.
例如,
[
{
'filename': 'a.jpg',
'width': 1280,
'height': 720,
'ann': {
'bboxes': <np.ndarray, float32> (n, 4),
'labels': <np.ndarray, int64> (n, ),
'bboxes_ignore': <np.ndarray, float32> (k, 4),
'labels_ignore': <np.ndarray, int64> (k, ) (optional field)
}
},
...
]
对于定制数据集,有两种处理⽅式:
[1] - 在线转换数据标注格式
⾃定义⼀个新的 Dataset class,继承于 CustomDataset,并重写 load_annotations(self, ann_file) 和 get_ann_info(self, idx),类似于 mmdet/datasets/coco.py 和 mmdet/datasets/voc.py.
[2] - 离线转换数据标注格式
将定制数据集的标注格式,转化为以上期望的格式,并保存为 pickle ⽂件或 json ⽂件,类似于
tools/convert_datasets/pascal_voc.py. 然后,即可使⽤ CustomDataset.
pascal_voc.py:
import argparse
import os.path as osp
ElementTree as ET
import mmcv
import numpy as np
import voc_classes
label_ids = {name: i + 1 for i, name in enumerate(voc_classes())}
def parse_xml(args):
xml_path, img_path = args
tree = ET.parse(xml_path)
root = t()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
bboxes = []
labels = []
bboxes_ignore = []
labels_ignore = []
for obj in root.findall('object'):
name = obj.find('name').text
label = label_ids[name]
difficult = int(obj.find('difficult').text)
bnd_box = obj.find('bndbox')
bbox = [
int(bnd_box.find('xmin').text),
int(bnd_box.find('ymin').text),
int(bnd_box.find('xmax').text),
int(bnd_box.find('ymax').text)
]
if difficult:
bboxes_ignore.append(bbox)
labels_ignore.append(label)
labels_ignore.append(label)
else:
bboxes.append(bbox)通用模型
labels.append(label)
if not bboxes:
bboxes = np.zeros((0, 4))
labels = np.zeros((0, ))
else:
bboxes = np.array(bboxes, ndmin=2) - 1
labels = np.array(labels)
if not bboxes_ignore:
bboxes_ignore = np.zeros((0, 4))
labels_ignore = np.zeros((0, ))
else:
bboxes_ignore = np.array(bboxes_ignore, ndmin=2) - 1
丙烷脱氢制丙烯>虹膜定位
labels_ignore = np.array(labels_ignore)
annotation = {
'filename': img_path,
'width': w,
'height': h,
'ann': {
'bboxes': bboxes.astype(np.float32),
'labels': labels.astype(np.int64),
'bboxes_ignore': bboxes_ignore.astype(np.float32),
'labels_ignore': labels_ignore.astype(np.int64)
}
}
return annotation
def cvt_annotations(devkit_path, years, split, out_file):
if not isinstance(years, list):
years = [years]
annotations = []
for year in years:
filelist = osp.join(devkit_path, 'VOC{}/ImageSets/Main/{}.txt'.format(
year, split))
if not osp.isfile(filelist):
print('filelist does not exist: {}, skip voc{} {}'.format(
filelist, year, split))
return
img_names = mmcv.list_from_file(filelist)
xml_paths = [
osp.join(devkit_path, 'VOC{}/Annotations/{}.xml'.format(
year, img_name)) for img_name in img_names
]
img_paths = [
'VOC{}/JPEGImages/{}.jpg'.format(year, img_name)
for img_name in img_names
]
part_annotations = ack_progress(parse_xml,
list(zip(xml_paths, img_paths)))
mmcv.dump(annotations, out_file)
return annotations
def parse_args():
parser = argparse.ArgumentParser(
description='Convert PASCAL VOC annotations to mmdetection format')    parser.add_argument('devkit_path', help='pascal voc devkit path')
parser.add_argument('-o', '--out-dir', help='output path')
args = parser.parse_args()
return args

本文发布于:2024-09-26 02:20:52,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/343515.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   训练   标注
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议