引言
在test阶段有以下几个方法:
single_gpu_test()
:顾名思义,就是单GPU测试,该方法在main()
中调用,当不分布式测试的时候,则运行次测试方法,该方法的实现中,其实是调用了检测器测试过程的forward()
前向计算过程,以cascade_rcnn为例,在cascade_rcnn的父类中的forward()
方法中,通过判断test_mode
当前处于训练还是测试阶段,来调用在cascade_rcnn类中重写的forwad_train()
和simple_test()
方法,来完成训练和测试的前向传播过程。multi_gpu_test()
:同上。collect_results()
:parse_args()
:读取命令行参数。同训练文件train.py中的parse_args()
作用一样。这边就不讲了main()
:该py文件的主体过程,在main中,读取配置文件,读取模型文件,读取数据集,加载检查点模型,然后开始进行测试,并将测试过程的前向传播的结果,进行eval,这个eval过程,主要是调用了cocoEval
的API来完成的(cocoEval.evaluate()
、cocoEval.accumulate()
、cocoEval.summarize()
,这些在coco_utils.py
中被调用)。
单gpu测试和多gpu测试代码:
# coding=gbk
import argparse
import os
import os.path as osp
import shutil
import tempfile
import mmcv
import torch
import torch.distributed as dist
from mmcv.runner import load_checkpoint, get_dist_info
from mmcv.parallel import MMDataParallel, MMDistributedDataParallel
from mmdet.apis import init_dist
from mmdet.core import results2json, coco_eval, wrap_fp16_model
from mmdet.datasets import build_dataloader, build_dataset
from mmdet.models import build_detector
def single_gpu_test(model, data_loader, show=False):# 单 gpu 测试
model.eval()
#model.eval() 将通知你所有的图层你处于评估模式,这样,batchnorm或dropout图层将在eval模式而不是训练模式下工作。
#torch.no_grad() 影响autograd引擎并停用它。它将减少内存使用并加快计算速度,但将无法进行反向提升(在eval脚本中不需要)。
results = []
dataset = data_loader.dataset # Dataset对象
prog_bar = mmcv.ProgressBar(len(dataset)) # 进度条
for i, data in enumerate(data_loader): # data是个字典
with torch.no_grad(): # with torch.no_grad() 使用 no_grad 上下文管理器,处理autograd引擎并阻止它计算渐变
result = model(return_loss=False, rescale=not show, **data) # result = model()??? 传入data,调用的应该是测试函数
results.append(result)
if show:
model.module.show_result(data, result, dataset.img_norm_cfg) # show_result() 在 module类定义的方法里
batch_size = data['img'][0].size(0) # data是个字典:有字段img,img_meta。
#'img':[tensor([[[[....]]]])]
#'img_meta': [DataContainer([[{'ori_shape': (600, 800, 3), 'img_shape': (800, 1067, 3), 'pad_shape': (800, 1088, 3), 'scale_factor': 1.3333333333333333, 'flip': False}]])]
#print(data)
#print(data['img']) # 是个tensor
#print(data['img'][0]) # 是个 tensor
#print(batch_size) # batch_size = 1
#exit("输出数据查看结束!")
for _ in