mmdetection入门介绍-test.py解析

三、test.py解析

tools/test.py负责对已经训练好的模型进行评估,程序代码整体比较长,这里按照程序流程来部分梳理

3.1 函数入口

    args = parse_args()

    assert args.out or args.show or args.json_out, \
        ('Please specify at least one operation (save or show the results) '
         'with the argument "--out" or "--show" or "--json_out"')

    if args.out is not None and not args.out.endswith(('.pkl', '.pickle')):
        raise ValueError('The output file must be a pkl file.')

    if args.json_out is not None and args.json_out.endswith('.json'):
        args.json_out = args.json_out[:-5]

    cfg = mmcv.Config.fromfile(args.config) # 读取配置文件加载dict
    # set cudnn_benchmark
    # 单尺度开启可以加速
    if cfg.get('cudnn_benchmark', False):
        torch.backends.cudnn.benchmark = True
    cfg.model.pretrained = None
    cfg.data.test.test_mode = True


    # init distributed env first, since logger depends on the dist info.
    if args.launcher == 'none':
        distributed = False
    else:
        distributed = True
        init_dist(args.launcher, **cfg.dist_params)

    # build the dataloader
    # TODO: support multiple images per gpu (only minor changes are needed)
    dataset = build_dataset(cfg.data.test)
    data_loader = build_dataloader(
        dataset,
        imgs_per_gpu=1,
        workers_per_gpu=cfg.data.workers_per_gpu,
        dist=distributed,
        shuffle=False)

    # build the model and load checkpoint
    model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg)
    fp16_cfg = cfg.get('fp16', None)
    if fp16_cfg is not None:
        wrap_fp16_model(model)
    checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')
    # old versions did not save class info in checkpoints, this walkaround is
    # for backward compatibility
    if 'CLASSES' in checkpoint['meta']:
        model.CLASSES = checkpoint['meta']['CLASSES']
    else:
        model.CLASSES = dataset.CLASSES


    if not distributed:
        model = MMDataParallel(model, device_ids=[0])
        outputs = single_gpu_test(model, data_loader, args.show)
    else:
        model = MMDistributedDataParallel(model.cuda())
        outputs = multi_gpu_test(model, data_loader, args.tmpdir)


    rank, _ = get_dist_info()
    if args.out and rank == 0:
        print('\nwriting results to {}'.format(args.out))
        mmcv.dump(outputs, args.out)
        eval_types = args.eval
        if eval_types:
            print('Starting evaluate {}'.format(' and '.join(eval_types)))
            if eval_types == ['proposal_fast']:
                result_file = args.out
                coco_eval(result_file, eval_types, dataset.coco)
            else:
                if not isinstance(outputs[0], dict):
                    result_files = results2json(dataset, outputs, args.out)
                    coco_eval(result_files, eval_types, dataset.coco)
                else:
                    for name in outputs[0]:
                        print('\nEvaluating {}'.format(name))
                        outputs_ = [out[name] for out in outputs]
                        result_file = args.out + '.{}'.format(name)
                        result_files = results2json(dataset, outputs_,
                                                    result_file)
                        coco_eval(result_files, eval_types, dataset.coco)

    # Save predictions in the COCO json format
    if args.json_out and rank == 0:
        if not isinstance(outputs[0], dict):
            results2json(dataset, outputs, args.json_out)
        else:
            for name in outputs[0]:
                outputs_ = [out[name] for out in outputs]
                result_file = args.json_out + '.{}'.format(name)
                results2json(dataset, outputs_, result_file)

if __name__ == '__main__':
    main()

3.2 参数读取

首先是参数输入

def parse_args():
    parser = argparse.ArgumentParser(description='MMDet test detector')
    parser.add_argument('config', help='test config file path')
    parser.add_argument('checkpoint', help='checkpoint file')
    parser.add_argument('--out', help='output result file')
    parser.add_argument(
        '--json_out',
        help='output result file name without extension',
        type=str)
    parser.add_argument(
        '--eval',
        type=str,
        nargs='+',
        choices=['proposal', 'proposal_fast', 'bbox', 'segm', 'keypoints'],
        help='eval types')
    parser.add_argument('--show', action='store_true', help='show results')
    parser.add_argument('--tmpdir', help='tmp dir for writing some results')
    parser.add_argument(
        '--launcher',
        choices=['none', 'pytorch', 'slurm', 'mpi'],
        default='none',
        help='job launcher')
    parser.add_argument('--local_rank', type=int, default=0)
    args = parser.parse_args()
    if 'LOCAL_RANK' not in os.environ:
        os.environ['LOCAL_RANK'] = str(args.local_rank)
    return args

这里参照上面的代码解释,就可以知道怎么用了,程序进去后,对参数进行了一定的要求。

后面就来到了读取配置文件,设置pretrained=None,test_mode=True

    cfg = mmcv.Config.fromfile(args.config)
    # set cudnn_benchmark
    if cfg.get('cudnn_benchmark', False):
        torch.backends.cudnn.benchmark = True
    cfg.model.pretrained = None
    cfg.data.test.test_mode = True

读取分布式信息

    # init distributed env first, since logger depends on the dist info.
    if args.launcher == 'none':
        distributed = False
    else:
        distributed = True
        init_dist(args.launcher, **cfg.dist_params)

这里如果你没有设置的话,默认是非分布式训练,如果设置了分布式训练,这里就会读取分布式训练配置信息。

接下来就开始读取数据集test配置的信息了

# build the dataloader
# TODO: support multiple images per gpu (only minor changes are needed)
dataset = build_dataset(cfg.data.test)
data_loader = build_dataloader(
    dataset,
    imgs_per_gpu=1,#每次测试的时候1张图片
    workers_per_gpu=cfg.data.workers_per_gpu,
    dist=distributed,
    shuffle=False)#打乱每次测试的数据

主要是通过读取cfg.data.test内部参数,

3.3 导入model和checkpoints

# build the model and load checkpoint
model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg)
fp16_cfg = cfg.get('fp16', None)
if fp16_cfg is not None:
wrap_fp16_model(model)
checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')

这里我们可以看到build_detector函数,

def build_detector(cfg, train_cfg=None, test_cfg=None):
    return build(cfg, DETECTORS, dict(train_cfg=train_cfg, test_cfg=test_cfg))

def build(cfg, registry, default_args=None):
    if isinstance(cfg, list):
        modules = [
            build_from_cfg(cfg_, registry, default_args) for cfg_ in cfg
        ]
        return nn.Sequential(*modules)
    else:
        return build_from_cfg(cfg, registry, default_args)

模型会读取config文件夹下面的train_cfg和test_cfg

# training and testing settings
train_cfg = dict(
    assigner=dict(
        type='MaxIoUAssigner',#rpn网络的正负样本划分
        pos_iou_thr=0.5,      #正样本的IOU阈值
        neg_iou_thr=0.4,      #负样本的IOU阈值
        min_pos_iou=0,        #正样本的IOU最小值
        ignore_iof_thr=-1),   #忽略bbox的阈值
    allowed_border=-1,        #不允许在bbox周围外扩一定的像素
    pos_weight=-1,            #正负样本权重,-1表示不改变原始的权重
    debug=False)
test_cfg = dict(
    nms_pre=1000,
    min_bbox_size=0,
    score_thr=0.05,
    nms=dict(type='nms', iou_thr=0.5),
    #nms=dict(type='soft_nms', iou_thr=0.5),
    max_per_img=100)

有了数据集信息,模型参数和checkpoints,就可以测试结果了

# old versions did not save class info in checkpoints, this walkaround is
# for backward compatibility
if 'CLASSES' in checkpoint['meta']:
    model.CLASSES = checkpoint['meta']['CLASSES']
else:
    model.CLASSES = dataset.CLASSES
if not distributed:
    model = MMDataParallel(model, device_ids=[0])
    outputs = single_gpu_test(model, data_loader, args.show)
else:
    model = MMDistributedDataParallel(model.cuda())
    outputs = multi_gpu_test(model, data_loader, args.tmpdir)

根据输入的信息,对应选择进去到单GPU和多GPU测试

def single_gpu_test(model, data_loader, show=False):
    model.eval()
    results = []
    dataset = data_loader.dataset
    prog_bar = mmcv.ProgressBar(len(dataset))
    for i, data in enumerate(data_loader):
        with torch.no_grad():
            result = model(return_loss=False, rescale=not show, **data)
        results.append(result)

        if show:
            model.module.show_result(data, result)

        batch_size = data['img'][0].size(0)
        for _ in range(batch_size):
            prog_bar.update()
    return results

def multi_gpu_test(model, data_loader, tmpdir=None):
    model.eval()
    results = []
    dataset = data_loader.dataset
    rank, world_size = get_dist_info()
    if rank == 0:
        prog_bar = mmcv.ProgressBar(len(dataset))
    for i, data in enumerate(data_loader):
        with torch.no_grad():
            result = model(return_loss=False, rescale=True, **data)
        results.append(result)

        if rank == 0:
            batch_size = data['img'][0].size(0)
            for _ in range(batch_size * world_size):
                prog_bar.update()

    # collect results from all ranks
    results = collect_results(results, len(dataset), tmpdir)

    return results

无论是单GPU测试和多GPU测试,模型都调用了torch.nn.eval()函数,进入评估部分

通过遍历整个data_loader,取消梯度运算,,调用model函数最终的结果都append到一个results的一个数组里面,最后在进度条中显示出来。

for i, data in enumerate(data_loader):
    with torch.no_grad():
        result = model(return_loss=False, rescale=True, **data)
    results.append(result)

    if show:
        model.module.show_result(data, result)

    batch_size = data['img'][0].size(0)
    for _ in range(batch_size):
        prog_bar.update()  #进度条更新

如果你没有设置eval_types的话,测试的最终结果就会保存在–out=eval/results.pkl文件下。具体测评方式在下面章节会继续讲到。

其他参考
这里是mmdetection入门介绍 前言 部分
这里是mmdetection入门介绍 test.py解析 部分
这里是mmdetection入门介绍 train.py解析 部分
这里是mmdetection入门介绍 模型解析 部分

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: mmdetection test.py 是一个命令行工具,用于在mmdetection框架中进行模型测试。通过该工具,可以加载训练好的模型,对测试集进行预测,并输出预测结果。在使用该工具时,需要指定测试集的路径、模型的路径、输出结果的路径等参数。具体使用方法可以参考mmdetection官方文档。 ### 回答2: MMDetection是一个基于PyTorch的开源目标检测框架,可用于各种物体检测任务。在MMDetection中,test.py是用于测试训练好的模型的主要脚本之一。 使用test.py脚本,需要先准备测试集数据和训练好的模型。测试集数据通常包括一组或多组待检测的图像,这些图像需要与训练集数据的格式相同。训练好的模型可以是从已有的预训练模型微调而来,也可以是从头开始训练的。 在准备好数据和模型后,可以使用test.py脚本进行测试。具体步骤如下: 1. 修改配置文件 首先需要编辑配置文件,将项目的路径和测试文件路径等参数设置正确。配置文件通常保存在config文件夹中,其中包括运行模型的参数、模型架构、训练方案等。可用记事本或其他编辑器打开该文件进行修改。 2. 运行测试 在命令行中输入以下代码即可运行测试 python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}] [--show] [--show-dir ${SHOW_DIR}] 其中,${CONFIG_FILE}是指配置文件的路径;${CHECKPOINT_FILE}是指训练好的模型的路径;${RESULT_FILE}是指测试结果保存的路径;${EVAL_METRICS}是指测试评价指标,如AP、AR等;--show和--show-dir参数是可选的,前者用于显示测试结果的图像,后者用于指定显示结果的文件夹路径。 3. 测试结果 测试完成后,可以查看测试结果。如果指定了--out参数,则测试结果会保存在该路径下,可以使用文本编辑器或其他工具打开查看。如果使用了--show参数,则测试结果的图像会显示在屏幕上,可以逐一查看每张图片的检测结果。 总之,MMDetectiontest.py脚本是一个十分重要的工具,它可以方便快捷地进行目标检测模型的测试。需要注意的是,在实际应用中,还需根据具体任务和数据情况进行适当的参数调整和模型优化,以获得更佳的检测结果。 ### 回答3: mmdetection是一个基于PyTorch框架的目标检测工具,提供了训练和测试目标检测模型的工具链。其中test.py是用来测试训练好的目标检测模型的脚本。 在使用mmdetection之前,需要先安装相关的依赖包和mmdetection。可以使用以下命令安装: ``` pip install -r requirements/build.txt pip install -v -e . ``` 安装完成后,需要下载数据集和预训练模型,可以通过以下命令进行下载: ``` python tools/get_data.py ``` 然后,需要准备测试集的数据和相应的配置文件。测试集的数据应该放在一个文件夹中,并且每个图片需要有一个对应的xml文件。配置文件可以在configs文件夹中找到,需要选择与训练时使用的配置文件相同的配置文件。 接下来就可以运行test.py脚本进行测试,例如: ``` python tools/test.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py work_dirs/faster_rcnn_r50_fpn_1x_coco/epoch_12.pth --eval bbox ``` 其中,第一个参数是配置文件的路径,第二个参数是模型权重文件的路径,第三个参数是评估的指标,这里选择bbox指标,即bounding box的准确率和AP值。运行完后,会在结果文件夹中生成测试结果。 mmdetectiontest.py脚本还提供了很多其他的参数,可以通过以下命令查看: ``` python tools/test.py --help ``` 总之,mmdetection test.py可以方便地测试训练好的目标检测模型,并输出评估结果,可用于模型优化和验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值