def init_pose_model(config, checkpoint=None, device='cuda:0'): """Initialize a pose model from config file. Args: config (str or :obj:`mmcv.Config`): Config file path or the config object. checkpoint (str, optional): Checkpoint path. If left as None, the model will not load any weights. Returns: nn.Module: The constructed detector. """ if isinstance(config, str): config = mmcv.Config.fromfile(config) elif not isinstance(config, mmcv.Config): raise TypeError('config must be a filename or Config object, ' f'but got {type(config)}') config.model.pretrained = None model = build_posenet(config.model) if checkpoint is not None: # load model checkpoint load_checkpoint(model, checkpoint, map_location=device) # save the config in the model for convenience model.cfg = config model.to(device) model.eval() return model
def main(): args = parse_args() 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 args.work_dir = osp.join('./work_dirs', osp.splitext(osp.basename(args.config))[0]) mmcv.mkdir_or_exist(osp.abspath(args.work_dir)) # 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, dict(test_mode=True)) data_loader = build_dataloader(dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_posenet(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) _ = load_checkpoint(model, args.checkpoint, map_location='cpu') # for backward compatibility if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader) 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() eval_config = cfg.get('eval_config', {}) eval_config = merge_configs(eval_config, dict(metrics=args.eval)) if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) dataset.evaluate(outputs, args.work_dir, **eval_config)
def test_config_build_detector(): """Test that all detection models defined in the configs can be initialized.""" from mmcv import Config from mmpose.models import build_posenet config_dpath = _get_config_directory() print(f'Found config_dpath = {config_dpath}') import glob config_fpaths = list(glob.glob(join(config_dpath, '**', '*.py'))) config_fpaths = [p for p in config_fpaths if p.find('_base_') == -1] config_names = [relpath(p, config_dpath) for p in config_fpaths] print(f'Using {len(config_names)} config files') for config_fname in config_names: config_fpath = join(config_dpath, config_fname) config_mod = Config.fromfile(config_fpath) print(f'Building detector, config_fpath = {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_posenet(config_mod.model) assert detector is not None optimizer = build_optimizer(detector, config_mod.optimizer) assert isinstance(optimizer, torch.optim.Optimizer)
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_posenet(cfg.model) model = model.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(f'{split_line}\nInput shape: {input_shape}\n' f'Flops: {flops}\nParams: {params}\n{split_line}') 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 test_interhand3d_forward(): # model settings model_cfg = dict(type='Interhand3D', pretrained='torchvision://resnet50', backbone=dict(type='ResNet', depth=50), keypoint_head=dict( type='Interhand3DHead', keypoint_head_cfg=dict( in_channels=2048, out_channels=21 * 64, depth_size=64, num_deconv_layers=3, num_deconv_filters=(256, 256, 256), num_deconv_kernels=(4, 4, 4), ), root_head_cfg=dict( in_channels=2048, heatmap_size=64, hidden_dims=(512, ), ), hand_type_head_cfg=dict( in_channels=2048, num_labels=2, hidden_dims=(512, ), ), loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True), loss_root_depth=dict(type='L1Loss'), loss_hand_type=dict(type='BCELoss', use_target_weight=True), ), train_cfg={}, test_cfg=dict(flip_test=True, shift_heatmap=True)) detector = build_posenet(model_cfg) detector.init_weights() input_shape = (2, 3, 256, 256) mm_inputs = _demo_mm_inputs(input_shape) imgs = mm_inputs.pop('imgs') target = mm_inputs.pop('target') target_weight = mm_inputs.pop('target_weight') img_metas = mm_inputs.pop('img_metas') # Test forward train losses = detector.forward(imgs, target, target_weight, img_metas, return_loss=True) assert isinstance(losses, dict) # Test forward test with torch.no_grad(): _ = detector.forward(imgs, img_metas=img_metas, return_loss=False) _ = detector.forward_dummy(imgs)
def main(): args = parse_args() cfg = Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True # build the dataloader dataset = build_dataset(cfg.data.val) data_loader = build_dataloader( dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=False, shuffle=False) # build the model and load checkpoint model = build_posenet(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) if args.fuse_conv_bn: model = fuse_conv_bn(model) model = MMDataParallel(model, device_ids=[0]) # the first several iterations may be very slow so skip them num_warmup = 5 pure_inf_time = 0 # benchmark with total batch and take the average for i, data in enumerate(data_loader): torch.cuda.synchronize() start_time = time.perf_counter() with torch.no_grad(): model(return_loss=False, **data) torch.cuda.synchronize() elapsed = time.perf_counter() - start_time if i >= num_warmup: pure_inf_time += elapsed if (i + 1) % args.log_interval == 0: its = (i + 1 - num_warmup) / pure_inf_time print(f'Done item [{i + 1:<3}], {its:.2f} items / s') print(f'Overall average: {its:.2f} items / s') print(f'Total time: {pure_inf_time:.2f} s')
def load_model(cfg, ckp_link): """ Loads a model from given mmcv.Config file and the related weights from the checkpoint link. Arguments: cfg mmcv.Config for the model ckp_link link to download the model's weights from Returns: model nn.Module """ model = build_posenet(cfg.model) load_checkpoint(model, ckp_link, map_location='cpu') model = MMDataParallel(model, device_ids=[0]) # device id, just set first cuda GPU return model
def load_model(cfg, ckp_link): """ Loads a model from given mmcv.Config file and the related weights from the checkpoint link. Arguments: cfg mmcv.Config for the model ckp_link link to download the model's weights from Returns: model nn.Module """ model = build_posenet(cfg.model) load_checkpoint(model, ckp_link, map_location='cpu') device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model.to(device) return model
def test_pose_lifter_forward(): # Test forward train model_cfg = dict(type='PoseLifter', pretrained=None, backbone=dict(type='TCN', in_channels=2 * 17), keypoint_head=dict( type='TemporalRegressionHead', in_channels=1024, num_joints=16, max_norm=1.0, loss_keypoint=dict(type='MPJPELoss'), test_cfg=dict(restore_global_position=True)), train_cfg=dict(), test_cfg=dict()) cfg = mmcv.Config({'model': model_cfg}) detector = build_posenet(cfg.model) detector.init_weights() inputs = _create_inputs(joint_num_in=17, joint_channel_in=2, joint_num_out=16, joint_channel_out=3, seq_len=27, batch_size=8) losses = detector.forward(inputs['input'], inputs['target'], inputs['target_weight'], inputs['metas'], return_loss=True) assert isinstance(losses, dict) # Test forward test with torch.no_grad(): _ = detector.forward(inputs['input'], inputs['target'], inputs['target_weight'], inputs['metas'], return_loss=False) _ = detector.forward_dummy(inputs['input'])
def main(): args = parse_args() if len(args.shape) == 1: input_shape = (1, 3, args.shape[0], args.shape[0]) elif len(args.shape) == 2: input_shape = ( 1, 3, ) + tuple(args.shape) else: raise ValueError('invalid input shape') cfg = Config.fromfile(args.config) model = build_posenet(cfg.model) model.eval() if args.with_head and hasattr(model, 'forward_with_head'): model.forward = model.forward_with_head elif not args.with_head and hasattr(model, 'forward_without_head'): model.forward = model.forward_without_head else: raise NotImplementedError( 'FLOPs counter is currently not currently supported with {}'. format(model.__class__.__name__)) df = model_stats(model, input_shape) print(df) if args.out_file: df.to_html(args.out_file + '.html') df.to_csv(args.out_file + '.csv') # 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() cfg = Config.fromfile(args.config) if args.options is not None: cfg.merge_from_dict(args.options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True # work_dir is determined in this priority: CLI > segment in file > filename if args.work_dir is not None: # update configs according to CLI args if args.work_dir is not None cfg.work_dir = args.work_dir elif cfg.get('work_dir', None) is None: # use config filename as default work_dir if cfg.work_dir is None cfg.work_dir = osp.join('./work_dirs', osp.splitext(osp.basename(args.config))[0]) if args.resume_from is not None: cfg.resume_from = args.resume_from if args.gpu_ids is not None: cfg.gpu_ids = args.gpu_ids else: cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus) if args.autoscale_lr: # apply the linear scaling rule (https://arxiv.org/abs/1706.02677) cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 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, f'{timestamp}.log') 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([(f'{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(f'Distributed training: {distributed}') logger.info(f'Config:\n{cfg.pretty_text}') # set random seeds if args.seed is not None: logger.info(f'Set random seed to {args.seed}, ' f'deterministic: {args.deterministic}') set_random_seed(args.seed, deterministic=args.deterministic) cfg.seed = args.seed meta['seed'] = args.seed model = build_posenet(cfg.model) 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 mmpose version, config file content # checkpoints as meta data cfg.checkpoint_config.meta = dict( mmpose_version=__version__ + get_git_hash(digits=7), config=cfg.pretty_text, ) train_model( model, datasets, cfg, distributed=distributed, validate=(not args.no_validate), timestamp=timestamp, meta=meta)
def test_pose_lifter_forward(): # Test forward train for supervised learning with pose model only model_cfg = dict(type='PoseLifter', pretrained=None, backbone=dict(type='TCN', in_channels=2 * 17), keypoint_head=dict( type='TemporalRegressionHead', in_channels=1024, num_joints=16, max_norm=1.0, loss_keypoint=dict(type='MPJPELoss'), test_cfg=dict(restore_global_position=True)), train_cfg=dict(), test_cfg=dict()) cfg = mmcv.Config({'model': model_cfg}) detector = build_posenet(cfg.model) detector.init_weights() inputs = _create_inputs(joint_num_in=17, joint_channel_in=2, joint_num_out=16, joint_channel_out=3, seq_len=27, batch_size=8) losses = detector.forward(inputs['input'], inputs['target'], inputs['target_weight'], inputs['metas'], return_loss=True) assert isinstance(losses, dict) # Test forward test for supervised learning with pose model only with torch.no_grad(): _ = detector.forward(inputs['input'], inputs['target'], inputs['target_weight'], inputs['metas'], return_loss=False) _ = detector.forward_dummy(inputs['input']) # Test forward train for semi-supervised learning model_cfg = dict( type='PoseLifter', pretrained=None, backbone=dict(type='TCN', in_channels=2 * 17), keypoint_head=dict(type='TemporalRegressionHead', in_channels=1024, num_joints=17, loss_keypoint=dict(type='MPJPELoss'), test_cfg=dict(restore_global_position=True)), traj_backbone=dict(type='TCN', in_channels=2 * 17), traj_head=dict(type='TemporalRegressionHead', in_channels=1024, num_joints=1, loss_keypoint=dict(type='MPJPELoss'), is_trajectory=True), loss_semi=dict(type='SemiSupervisionLoss', joint_parents=[ 0, 0, 1, 2, 0, 4, 5, 0, 7, 8, 9, 8, 11, 12, 8, 14, 15 ]), train_cfg=dict(), test_cfg=dict()) cfg = mmcv.Config({'model': model_cfg}) detector = build_posenet(cfg.model) detector.init_weights() inputs = _create_inputs(joint_num_in=17, joint_channel_in=2, joint_num_out=17, joint_channel_out=3, seq_len=27, batch_size=8, semi=True) losses = detector.forward(**inputs, return_loss=True) assert isinstance(losses, dict) assert 'proj_loss' in losses # Test forward test for semi-supervised learning with torch.no_grad(): _ = detector.forward(**inputs, return_loss=False) _ = detector.forward_dummy(inputs['input']) # Test forward train for supervised learning with pose model and trajectory # model sharing one backbone model_cfg = dict(type='PoseLifter', pretrained=None, backbone=dict(type='TCN', in_channels=2 * 17), keypoint_head=dict( type='TemporalRegressionHead', in_channels=1024, num_joints=17, loss_keypoint=dict(type='MPJPELoss'), test_cfg=dict(restore_global_position=True)), traj_head=dict(type='TemporalRegressionHead', in_channels=1024, num_joints=1, loss_keypoint=dict(type='MPJPELoss'), is_trajectory=True), train_cfg=dict(), test_cfg=dict()) cfg = mmcv.Config({'model': model_cfg}) detector = build_posenet(cfg.model) detector.init_weights() inputs = _create_inputs(joint_num_in=17, joint_channel_in=2, joint_num_out=17, joint_channel_out=3, seq_len=27, batch_size=8, semi=True) losses = detector.forward(**inputs, return_loss=True) assert isinstance(losses, dict) assert 'traj_loss' in losses # Test forward test for semi-supervised learning with pose model and # trajectory model sharing one backbone with torch.no_grad(): _ = detector.forward(**inputs, return_loss=False) _ = detector.forward_dummy(inputs['input'])
type=int, nargs='+', default=[1, 3, 256, 192], help='input size') args = parser.parse_args() return args if __name__ == '__main__': args = parse_args() assert args.opset_version == 11, 'MMPose only supports opset 11 now' cfg = mmcv.Config.fromfile(args.config) # build the model model = build_posenet(cfg.model) model = _convert_batchnorm(model) # onnx.export does not support kwargs if hasattr(model, 'forward_dummy'): model.forward = model.forward_dummy else: raise NotImplementedError( 'Please implement the forward method for exporting.') checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # conver model to onnx file pytorch2onnx(model, args.shape, opset_version=args.opset_version,
def main(): args = parse_args() cfg = Config.fromfile(args.config) if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True args.work_dir = osp.join('./work_dirs', osp.splitext(osp.basename(args.config))[0]) mmcv.mkdir_or_exist(osp.abspath(args.work_dir)) # 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 dataset = build_dataset(cfg.data.test, dict(test_mode=True)) dataloader_setting = dict(samples_per_gpu=1, workers_per_gpu=cfg.data.get( 'workers_per_gpu', 1), dist=distributed, shuffle=False, drop_last=False) dataloader_setting = dict(dataloader_setting, **cfg.data.get('test_dataloader', {})) data_loader = build_dataloader(dataset, **dataloader_setting) # print(data_loader) # build the model and load checkpoint model = build_posenet(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) load_checkpoint(model, args.checkpoint, map_location='cpu') if args.fuse_conv_bn: model = fuse_conv_bn(model) if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader) 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() eval_config = cfg.get('evaluation', {}) eval_config = merge_configs(eval_config, dict(metric=args.eval)) if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) results = dataset.evaluate(outputs, args.work_dir, **eval_config) for k, v in sorted(results.items()): print(f'{k}: {v}')
def main(): args = parse_args() cfg = Config.fromfile(args.config) if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) # set multi-process settings setup_multi_processes(cfg) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True # work_dir is determined in this priority: CLI > segment in file > filename if args.work_dir is not None: # update configs according to CLI args if args.work_dir is not None cfg.work_dir = args.work_dir elif cfg.get('work_dir', None) is None: # use config filename as default work_dir if cfg.work_dir is None cfg.work_dir = osp.join('./work_dirs', osp.splitext(osp.basename(args.config))[0]) mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir)) # 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 dataset = build_dataset(cfg.data.test, dict(test_mode=True)) # step 1: give default values and override (if exist) from cfg.data loader_cfg = { **dict(seed=cfg.get('seed'), drop_last=False, dist=distributed), **({} if torch.__version__ != 'parrots' else dict( prefetch_num=2, pin_memory=False, )), **dict((k, cfg.data[k]) for k in [ 'seed', 'prefetch_num', 'pin_memory', 'persistent_workers', ] if k in cfg.data) } # step2: cfg.data.test_dataloader has higher priority test_loader_cfg = { **loader_cfg, **dict(shuffle=False, drop_last=False), **dict(workers_per_gpu=cfg.data.get('workers_per_gpu', 1)), **dict(samples_per_gpu=cfg.data.get('samples_per_gpu', 1)), **cfg.data.get('test_dataloader', {}) } data_loader = build_dataloader(dataset, **test_loader_cfg) # build the model and load checkpoint model = build_posenet(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) load_checkpoint(model, args.checkpoint, map_location='cpu') if args.fuse_conv_bn: model = fuse_conv_bn(model) if not distributed: model = MMDataParallel(model, device_ids=[args.gpu_id]) outputs = single_gpu_test(model, data_loader) 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() eval_config = cfg.get('evaluation', {}) eval_config = merge_configs(eval_config, dict(metric=args.eval)) if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) results = dataset.evaluate(outputs, cfg.work_dir, **eval_config) for k, v in sorted(results.items()): print(f'{k}: {v}')