def test_rpn_forward(): model, train_cfg, test_cfg = _get_detector_cfg('rpn_r50_fpn_1x.py') model['pretrained'] = None from detection.mmdet.models import build_detector detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) input_shape = (1, 3, 224, 224) mm_inputs = _demo_mm_inputs(input_shape) imgs = mm_inputs.pop('imgs') img_metas = mm_inputs.pop('img_metas') # Test forward train gt_bboxes = mm_inputs['gt_bboxes'] losses = detector.forward(imgs, img_metas, gt_bboxes=gt_bboxes, return_loss=True) assert isinstance(losses, dict) # Test forward test with torch.no_grad(): img_list = [g[None, :] for g in imgs] batch_results = [] for one_img, one_meta in zip(img_list, img_metas): result = detector.forward([one_img], [[one_meta]], return_loss=False) batch_results.append(result)
def main(): args = parse_args() if len(args.shape) == 1: input_shape = (3, args.shape[0], args.shape[0]) elif len(args.shape) == 2: input_shape = (3, ) + tuple(args.shape) else: raise ValueError('invalid input shape') cfg = Config.fromfile(args.config) model = build_detector(cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg).cuda() model.eval() if hasattr(model, 'forward_dummy'): model.forward = model.forward_dummy else: raise NotImplementedError( 'FLOPs counter is currently not currently supported with {}'. format(model.__class__.__name__)) flops, params = get_model_complexity_info(model, input_shape) split_line = '=' * 30 print('{0}\nInput shape: {1}\nFlops: {2}\nParams: {3}\n{0}'.format( split_line, input_shape, flops, params)) print('!!!Please be cautious if you use the results in papers. ' 'You may need to check if all ops are supported and verify that the ' 'flops computation is correct.')
def main(): args = parse_args() if len(args.shape) == 1: img_shape = (1, 3, args.shape[0], args.shape[0]) elif len(args.shape) == 2: img_shape = (1, 3) + tuple(args.shape) elif len(args.shape) == 4: img_shape = tuple(args.shape) else: raise ValueError('invalid input shape') dummy_input = torch.randn(*img_shape, device='cuda') cfg = Config.fromfile(args.config) model = build_detector( cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg).cuda() print(args.checkpoint) if args.checkpoint: _ = load_checkpoint(model, args.checkpoint) if hasattr(model, 'forward_dummy'): model.forward = model.forward_dummy else: raise NotImplementedError( 'ONNX exporting is currently not currently supported with {}'. format(model.__class__.__name__)) torch.onnx.export(model, dummy_input, args.out, verbose=True)
def test_faster_rcnn_ohem_forward(): try: from torchvision import _C as C # NOQA except ImportError: import pytest raise pytest.skip('requires torchvision on cpu') model, train_cfg, test_cfg = _get_detector_cfg( 'faster_rcnn_ohem_r50_fpn_1x.py') model['pretrained'] = None # torchvision roi align supports CPU model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True from detection.mmdet.models import build_detector detector = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) input_shape = (1, 3, 256, 256) # Test forward train with a non-empty truth batch mm_inputs = _demo_mm_inputs(input_shape, num_items=[10]) imgs = mm_inputs.pop('imgs') img_metas = mm_inputs.pop('img_metas') gt_bboxes = mm_inputs['gt_bboxes'] gt_labels = mm_inputs['gt_labels'] losses = detector.forward(imgs, img_metas, gt_bboxes=gt_bboxes, gt_labels=gt_labels, return_loss=True) assert isinstance(losses, dict) from detection.mmdet.apis.train import parse_losses total_loss = float(parse_losses(losses)[0].item()) assert total_loss > 0 # Test forward train with an empty truth batch mm_inputs = _demo_mm_inputs(input_shape, num_items=[0]) imgs = mm_inputs.pop('imgs') img_metas = mm_inputs.pop('img_metas') gt_bboxes = mm_inputs['gt_bboxes'] gt_labels = mm_inputs['gt_labels'] losses = detector.forward(imgs, img_metas, gt_bboxes=gt_bboxes, gt_labels=gt_labels, return_loss=True) assert isinstance(losses, dict) from detection.mmdet.apis.train import parse_losses total_loss = float(parse_losses(losses)[0].item()) assert total_loss > 0
def _context_for_ohem(): try: from test_forward import _get_detector_cfg except ImportError: # Hack: grab testing utils from test_forward to make a context for ohem import sys from os.path import dirname sys.path.insert(0, dirname(__file__)) from test_forward import _get_detector_cfg model, train_cfg, test_cfg = _get_detector_cfg( 'faster_rcnn_ohem_r50_fpn_1x.py') model['pretrained'] = None # torchvision roi align supports CPU model['bbox_roi_extractor']['roi_layer']['use_torchvision'] = True from detection.mmdet.models import build_detector context = build_detector(model, train_cfg=train_cfg, test_cfg=test_cfg) return context
def main(): args = parse_args() assert args.out or args.eval or args.format_only or args.show, \ ('Please specify at least one operation (save/eval/format/show the ' 'results) with the argument "--out", "--eval", "--format_only" ' 'or "--show"') if args.eval and args.format_only: raise ValueError('--eval and --format_only cannot be both specified') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') 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) # 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(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if rank == 0: if args.out: print('\nwriting results to {}'.format(args.out)) mmcv.dump(outputs, args.out) kwargs = {} if args.options is None else args.options if args.format_only: dataset.format_results(outputs, **kwargs) if args.eval: dataset.evaluate(outputs, args.eval, **kwargs)
def main(): args = parse_args() cfg = Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True # update configs according to CLI args if args.work_dir is not None: cfg.work_dir = args.work_dir if args.resume_from is not None: cfg.resume_from = args.resume_from cfg.gpus = args.gpus if args.autoscale_lr: # apply the linear scaling rule (https://arxiv.org/abs/1706.02677) cfg.optimizer['lr'] = cfg.optimizer['lr'] * cfg.gpus / 8 # 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) # create work_dir mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir)) # init the logger before other steps timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime()) log_file = osp.join(cfg.work_dir, '{}.log'.format(timestamp)) logger = get_root_logger(log_file=log_file, log_level=cfg.log_level) # init the meta dict to record some important information such as # environment info and seed, which will be logged meta = dict() # log env info env_info_dict = collect_env() env_info = '\n'.join([('{}: {}'.format(k, v)) for k, v in env_info_dict.items()]) dash_line = '-' * 60 + '\n' logger.info('Environment info:\n' + dash_line + env_info + '\n' + dash_line) meta['env_info'] = env_info # log some basic info logger.info('Distributed training: {}'.format(distributed)) logger.info('Config:\n{}'.format(cfg.text)) # set random seeds if args.seed is not None: logger.info('Set random seed to {}, deterministic: {}'.format( args.seed, args.deterministic)) set_random_seed(args.seed, deterministic=args.deterministic) cfg.seed = args.seed meta['seed'] = args.seed model = build_detector( cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg) datasets = [build_dataset(cfg.data.train)] if len(cfg.workflow) == 2: val_dataset = copy.deepcopy(cfg.data.val) val_dataset.pipeline = cfg.data.train.pipeline datasets.append(build_dataset(val_dataset)) if cfg.checkpoint_config is not None: # save mmdet version, config file content and class names in # checkpoints as meta data cfg.checkpoint_config.meta = dict( mmdet_version=__version__, config=cfg.text, CLASSES=datasets[0].CLASSES) # add an attribute for visualization convenience model.CLASSES = datasets[0].CLASSES train_detector( model, datasets, cfg, distributed=distributed, validate=args.validate, timestamp=timestamp, meta=meta)
def main(): args = parse_args() assert args.out or args.show, \ ('Please specify at least one operation (save or show the results) ' 'with the argument "--out" or "--show"') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') 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 if args.workers == 0: args.workers = cfg.data.workers_per_gpu # 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) # set random seeds if args.seed is not None: set_random_seed(args.seed) if 'all' in args.corruptions: corruptions = [ 'gaussian_noise', 'shot_noise', 'impulse_noise', 'defocus_blur', 'glass_blur', 'motion_blur', 'zoom_blur', 'snow', 'frost', 'fog', 'brightness', 'contrast', 'elastic_transform', 'pixelate', 'jpeg_compression', 'speckle_noise', 'gaussian_blur', 'spatter', 'saturate' ] elif 'benchmark' in args.corruptions: corruptions = [ 'gaussian_noise', 'shot_noise', 'impulse_noise', 'defocus_blur', 'glass_blur', 'motion_blur', 'zoom_blur', 'snow', 'frost', 'fog', 'brightness', 'contrast', 'elastic_transform', 'pixelate', 'jpeg_compression' ] elif 'noise' in args.corruptions: corruptions = ['gaussian_noise', 'shot_noise', 'impulse_noise'] elif 'blur' in args.corruptions: corruptions = [ 'defocus_blur', 'glass_blur', 'motion_blur', 'zoom_blur' ] elif 'weather' in args.corruptions: corruptions = ['snow', 'frost', 'fog', 'brightness'] elif 'digital' in args.corruptions: corruptions = [ 'contrast', 'elastic_transform', 'pixelate', 'jpeg_compression' ] elif 'holdout' in args.corruptions: corruptions = ['speckle_noise', 'gaussian_blur', 'spatter', 'saturate'] elif 'None' in args.corruptions: corruptions = ['None'] args.severities = [0] else: corruptions = args.corruptions rank, _ = get_dist_info() aggregated_results = {} for corr_i, corruption in enumerate(corruptions): aggregated_results[corruption] = {} for sev_i, corruption_severity in enumerate(args.severities): # evaluate severity 0 (= no corruption) only once if corr_i > 0 and corruption_severity == 0: aggregated_results[corruption][0] = \ aggregated_results[corruptions[0]][0] continue test_data_cfg = copy.deepcopy(cfg.data.test) # assign corruption and severity if corruption_severity > 0: corruption_trans = dict(type='Corrupt', corruption=corruption, severity=corruption_severity) # TODO: hard coded "1", we assume that the first step is # loading images, which needs to be fixed in the future test_data_cfg['pipeline'].insert(1, corruption_trans) # print info print('\nTesting {} at severity {}'.format(corruption, corruption_severity)) # build the dataloader # TODO: support multiple images per gpu # (only minor changes are needed) dataset = build_dataset(test_data_cfg) data_loader = build_dataloader(dataset, imgs_per_gpu=1, workers_per_gpu=args.workers, 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(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir) if args.out and rank == 0: eval_results_filename = (osp.splitext(args.out)[0] + '_results' + osp.splitext(args.out)[1]) mmcv.dump(outputs, args.out) eval_types = args.eval if cfg.dataset_type == 'VOCDataset': if eval_types: for eval_type in eval_types: if eval_type == 'bbox': test_dataset = mmcv.runner.obj_from_dict( cfg.data.test, datasets) logger = 'print' if args.summaries else None mean_ap, eval_results = \ voc_eval_with_return( args.out, test_dataset, args.iou_thr, logger) aggregated_results[corruption][ corruption_severity] = eval_results else: print('\nOnly "bbox" evaluation \ is supported for pascal voc') else: if eval_types: print('Starting evaluate {}'.format( ' and '.join(eval_types))) if eval_types == ['proposal_fast']: result_file = args.out else: if not isinstance(outputs[0], dict): result_files = dataset.results2json( outputs, args.out) 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 = dataset.results2json( outputs_, result_file) eval_results = coco_eval_with_return( result_files, eval_types, dataset.coco) aggregated_results[corruption][ corruption_severity] = eval_results else: print('\nNo task was selected for evaluation;' '\nUse --eval to select a task') # save results after each evaluation mmcv.dump(aggregated_results, eval_results_filename) if rank == 0: # print filan results print('\nAggregated results:') prints = args.final_prints aggregate = args.final_prints_aggregate if cfg.dataset_type == 'VOCDataset': get_results(eval_results_filename, dataset='voc', prints=prints, aggregate=aggregate) else: get_results(eval_results_filename, dataset='coco', prints=prints, aggregate=aggregate)
def test_config_build_detector(): """ Test that all detection models defined in the configs can be initialized. """ from xdoctest.utils import import_module_from_path from detection.mmdet.models import build_detector config_dpath = _get_config_directory() print('Found config_dpath = {!r}'.format(config_dpath)) # import glob # config_fpaths = list(glob.glob(join(config_dpath, '**', '*.py'))) # config_names = [relpath(p, config_dpath) for p in config_fpaths] # Only tests a representative subset of configurations config_names = [ # 'dcn/faster_rcnn_dconv_c3-c5_r50_fpn_1x.py', # 'dcn/cascade_mask_rcnn_dconv_c3-c5_r50_fpn_1x.py', # 'dcn/faster_rcnn_dpool_r50_fpn_1x.py', 'dcn/mask_rcnn_dconv_c3-c5_r50_fpn_1x.py', # 'dcn/faster_rcnn_dconv_c3-c5_x101_32x4d_fpn_1x.py', # 'dcn/cascade_rcnn_dconv_c3-c5_r50_fpn_1x.py', # 'dcn/faster_rcnn_mdpool_r50_fpn_1x.py', # 'dcn/faster_rcnn_mdconv_c3-c5_group4_r50_fpn_1x.py', # 'dcn/faster_rcnn_mdconv_c3-c5_r50_fpn_1x.py', # --- # 'htc/htc_x101_32x4d_fpn_20e_16gpu.py', 'htc/htc_without_semantic_r50_fpn_1x.py', # 'htc/htc_dconv_c3-c5_mstrain_400_1400_x101_64x4d_fpn_20e.py', # 'htc/htc_x101_64x4d_fpn_20e_16gpu.py', # 'htc/htc_r50_fpn_1x.py', # 'htc/htc_r101_fpn_20e.py', # 'htc/htc_r50_fpn_20e.py', # --- 'cityscapes/mask_rcnn_r50_fpn_1x_cityscapes.py', # 'cityscapes/faster_rcnn_r50_fpn_1x_cityscapes.py', # --- # 'scratch/scratch_faster_rcnn_r50_fpn_gn_6x.py', # 'scratch/scratch_mask_rcnn_r50_fpn_gn_6x.py', # --- # 'grid_rcnn/grid_rcnn_gn_head_x101_32x4d_fpn_2x.py', 'grid_rcnn/grid_rcnn_gn_head_r50_fpn_2x.py', # --- 'double_heads/dh_faster_rcnn_r50_fpn_1x.py', # --- 'empirical_attention/faster_rcnn_r50_fpn_attention_0010_dcn_1x.py', # 'empirical_attention/faster_rcnn_r50_fpn_attention_1111_1x.py', # 'empirical_attention/faster_rcnn_r50_fpn_attention_0010_1x.py', # 'empirical_attention/faster_rcnn_r50_fpn_attention_1111_dcn_1x.py', # --- # 'ms_rcnn/ms_rcnn_r101_caffe_fpn_1x.py', # 'ms_rcnn/ms_rcnn_x101_64x4d_fpn_1x.py', # 'ms_rcnn/ms_rcnn_r50_caffe_fpn_1x.py', # --- # 'guided_anchoring/ga_faster_x101_32x4d_fpn_1x.py', # 'guided_anchoring/ga_rpn_x101_32x4d_fpn_1x.py', # 'guided_anchoring/ga_retinanet_r50_caffe_fpn_1x.py', # 'guided_anchoring/ga_fast_r50_caffe_fpn_1x.py', # 'guided_anchoring/ga_retinanet_x101_32x4d_fpn_1x.py', # 'guided_anchoring/ga_rpn_r101_caffe_rpn_1x.py', # 'guided_anchoring/ga_faster_r50_caffe_fpn_1x.py', 'guided_anchoring/ga_rpn_r50_caffe_fpn_1x.py', # --- 'foveabox/fovea_r50_fpn_4gpu_1x.py', # 'foveabox/fovea_align_gn_ms_r101_fpn_4gpu_2x.py', # 'foveabox/fovea_align_gn_r50_fpn_4gpu_2x.py', # 'foveabox/fovea_align_gn_r101_fpn_4gpu_2x.py', 'foveabox/fovea_align_gn_ms_r50_fpn_4gpu_2x.py', # --- # 'hrnet/cascade_rcnn_hrnetv2p_w32_20e.py', # 'hrnet/mask_rcnn_hrnetv2p_w32_1x.py', # 'hrnet/cascade_mask_rcnn_hrnetv2p_w32_20e.py', # 'hrnet/htc_hrnetv2p_w32_20e.py', # 'hrnet/faster_rcnn_hrnetv2p_w18_1x.py', # 'hrnet/mask_rcnn_hrnetv2p_w18_1x.py', # 'hrnet/faster_rcnn_hrnetv2p_w32_1x.py', # 'hrnet/faster_rcnn_hrnetv2p_w40_1x.py', 'hrnet/fcos_hrnetv2p_w32_gn_1x_4gpu.py', # --- # 'gn+ws/faster_rcnn_r50_fpn_gn_ws_1x.py', # 'gn+ws/mask_rcnn_x101_32x4d_fpn_gn_ws_2x.py', 'gn+ws/mask_rcnn_r50_fpn_gn_ws_2x.py', # 'gn+ws/mask_rcnn_r50_fpn_gn_ws_20_23_24e.py', # --- # 'wider_face/ssd300_wider_face.py', # --- 'pascal_voc/ssd300_voc.py', 'pascal_voc/faster_rcnn_r50_fpn_1x_voc0712.py', 'pascal_voc/ssd512_voc.py', # --- # 'gcnet/mask_rcnn_r4_gcb_c3-c5_r50_fpn_syncbn_1x.py', # 'gcnet/mask_rcnn_r16_gcb_c3-c5_r50_fpn_syncbn_1x.py', # 'gcnet/mask_rcnn_r4_gcb_c3-c5_r50_fpn_1x.py', # 'gcnet/mask_rcnn_r16_gcb_c3-c5_r50_fpn_1x.py', 'gcnet/mask_rcnn_r50_fpn_sbn_1x.py', # --- 'gn/mask_rcnn_r50_fpn_gn_contrib_2x.py', # 'gn/mask_rcnn_r50_fpn_gn_2x.py', # 'gn/mask_rcnn_r101_fpn_gn_2x.py', # --- # 'reppoints/reppoints_moment_x101_dcn_fpn_2x.py', 'reppoints/reppoints_moment_r50_fpn_2x.py', # 'reppoints/reppoints_moment_x101_dcn_fpn_2x_mt.py', 'reppoints/reppoints_partial_minmax_r50_fpn_1x.py', 'reppoints/bbox_r50_grid_center_fpn_1x.py', # 'reppoints/reppoints_moment_r101_dcn_fpn_2x.py', # 'reppoints/reppoints_moment_r101_fpn_2x_mt.py', # 'reppoints/reppoints_moment_r50_fpn_2x_mt.py', 'reppoints/reppoints_minmax_r50_fpn_1x.py', # 'reppoints/reppoints_moment_r50_fpn_1x.py', # 'reppoints/reppoints_moment_r101_fpn_2x.py', # 'reppoints/reppoints_moment_r101_dcn_fpn_2x_mt.py', 'reppoints/bbox_r50_grid_fpn_1x.py', # --- # 'fcos/fcos_mstrain_640_800_x101_64x4d_fpn_gn_2x.py', # 'fcos/fcos_mstrain_640_800_r101_caffe_fpn_gn_2x_4gpu.py', 'fcos/fcos_r50_caffe_fpn_gn_1x_4gpu.py', # --- 'albu_example/mask_rcnn_r50_fpn_1x.py', # --- 'libra_rcnn/libra_faster_rcnn_r50_fpn_1x.py', # 'libra_rcnn/libra_retinanet_r50_fpn_1x.py', # 'libra_rcnn/libra_faster_rcnn_r101_fpn_1x.py', # 'libra_rcnn/libra_faster_rcnn_x101_64x4d_fpn_1x.py', # 'libra_rcnn/libra_fast_rcnn_r50_fpn_1x.py', # --- # 'ghm/retinanet_ghm_r50_fpn_1x.py', # --- # 'fp16/retinanet_r50_fpn_fp16_1x.py', 'fp16/mask_rcnn_r50_fpn_fp16_1x.py', 'fp16/faster_rcnn_r50_fpn_fp16_1x.py' ] print('Using {} config files'.format(len(config_names))) for config_fname in config_names: config_fpath = join(config_dpath, config_fname) config_mod = import_module_from_path(config_fpath) config_mod.model config_mod.train_cfg config_mod.test_cfg print('Building detector, config_fpath = {!r}'.format(config_fpath)) # Remove pretrained keys to allow for testing in an offline environment if 'pretrained' in config_mod.model: config_mod.model['pretrained'] = None detector = build_detector(config_mod.model, train_cfg=config_mod.train_cfg, test_cfg=config_mod.test_cfg) assert detector is not None