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 # save config file to work dir mkdir_or_exist(cfg.work_dir) os.system('cp {} {}'.format(args.config, 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) # init logger before other steps logger = get_root_logger(cfg.log_level) logger.info('Distributed training: {}'.format(distributed)) # set random seeds if args.seed is not None: logger.info('Set random seedllL to {}'.format(args.seed)) set_random_seed(args.seed) train_dataset = build_dataset(cfg.data.train) if cfg.model.get('info_dir') is not None: mmcv.dump(dict(class_instance_num = train_dataset.class_instance_num.tolist()), osp.join(cfg.model.info_dir)) model = build_classifier( cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg) 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( config=cfg.text, CLASSES=train_dataset.CLASSES) # add an attribute for visualization convenience model.CLASSES = train_dataset.CLASSES train_classifier( model, train_dataset, cfg, distributed=distributed, validate=args.validate, logger=logger) logger.info(cfg.work_dir)
def save_feat(args=None): if args is None: args = parse_args() cfg = mmcv.Config.fromfile(args.config) cfg.work_dir = osp.abspath(osp.join(args.checkpoint, '..')) if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') epoch = args.checkpoint.split('.')[-2].split('_')[-1] if args.out is None: args.out = osp.join(cfg.work_dir, 'gt_and_feats_e{}.pkl'.format(epoch)) # 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) rank, _ = get_dist_info() # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None # build the dataloader if not cfg.model.get('savefeat', False): setattr(cfg.model, "savefeat", True) model = build_classifier(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility dataset_list = make_dataset_list(cfg) if osp.exists(args.out) and args.from_file: savedata = mmcv.load(args.out) else: savedata = [dict() for _ in range(len(dataset_list))] for d, dataset in enumerate(dataset_list): data_loader = build_dataloader( dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) gt_labels = [] for i in range(len(dataset)): ann = dataset.get_ann_info(i) gt_labels.append(ann['labels']) 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_get_feat(model, data_loader, args.show) else: model = MMDistributedDataParallel(model.cuda()) outputs = multi_gpu_get_feat(model, data_loader, args.tmpdir) if rank == 0: features = np.vstack(outputs) savedata[d].update(features=features, gt_labels=gt_labels) if rank == 0: print('\nsaving feats to {}'.format(args.out)) mmcv.dump(savedata, args.out) # change back to normal model model = build_classifier(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') if args.job == 'pnorm': save_outputs = [dict() for _ in range(len(dataset_list))] for d in range(len(dataset_list)): features, gt_labels = savedata[d]['features'], savedata[d]['gt_labels'] outputs = test_pnorm(features, head=model.head, p=2) save_outputs[d] = dict(outputs=outputs, gt_labels=gt_labels) mmcv.dump(save_outputs, osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch))) print('Test results of pnorm saved at {}'.format(osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch)))) elif args.job == 'eval_feat': if osp.exists(osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch))): test_results = mmcv.load(osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch)))[0]['outputs'] train_results = mmcv.load(osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch)))[1]['outputs'] else: test_results = None train_results = None # test_proto(train_features=savedata[1]['features'], test_features=savedata[0]['features'], # train_gt_labels=savedata[1]['gt_labels'], test_gt_labels=savedata[0]['gt_labels'], # cla_results=cla_results, save_name=cfg.work_dir + '/proto_compare.jpg') # exit() eval_feat(train_features=savedata[1]['features'], train_gt_labels=savedata[1]['gt_labels'], train_results=train_results, results=test_results, gt_labels=savedata[0]['gt_labels'], features=savedata[0]['features'], head=model.head, save_name=cfg.work_dir + '/eval_feat.jpg') elif args.job == 'eval_centroid': assert not args.testset_only save_outputs = [dict() for _ in range(len(dataset_list))] train_features, train_gt_labels = savedata[1]['features'], savedata[1]['gt_labels'] for d in range(len(dataset_list)): features, gt_labels = savedata[d]['features'], savedata[d]['gt_labels'] outputs = test_centroids(features, train_features, train_gt_labels) save_outputs[d] = dict(outputs=outputs, gt_labels=gt_labels) mmcv.dump(save_outputs, osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch))) print( 'Test results of centroids saved at {}'.format(osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch)))) exit() else: raise NameError
def main(): args = parse_args() cfg = mmcv.Config.fromfile(args.config) cfg.work_dir = osp.abspath(osp.join(args.checkpoint, '..')) 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.out is None: epoch = args.checkpoint.split('.')[-2].split('_')[-1] args.out = osp.join(cfg.work_dir, 'gt_and_results_e{}.pkl'.format(epoch)) # 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) rank, _ = get_dist_info() if args.from_file: savedata = mmcv.load(args.out) else: # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None # build the dataloader dataset_list = make_dataset_list(cfg, args.testset_only) # build the model and load checkpoint model = build_classifier(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') if osp.exists(args.out): savedata = mmcv.load(args.out) else: savedata = [dict() for _ in range(len(dataset_list))] for d, dataset in enumerate(dataset_list): if args.testset_only and d > 0: break data_loader = build_dataloader( dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) gt_labels = [] for i in range(len(dataset)): gt_ann = dataset.get_ann_info(i) gt_labels.append(gt_ann['labels']) 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) if rank == 0: savedata[d].update(gt_labels=gt_labels, outputs=np.vstack(outputs)) if rank == 0: print('\nwriting results to {}'.format(args.out)) mmcv.dump(savedata, args.out) img_prefixs = [] dataset_list = make_dataset_list(cfg, args.testset_only) img_ids = [[] for _ in range(len(dataset_list))] for d, dataset in enumerate(dataset_list): img_prefixs.append(dataset.img_prefix) img_infos = dataset.img_infos for i in range(len(dataset)): img_ids[d].append(img_infos[i]['id']) if rank == 0: display_dict = {} eval_metrics = args.eval dataset = build_dataset(cfg.data.test) display_dict['class'] = dataset.CLASSES for i, data in enumerate(savedata): if args.testset_only and i > 0: # test-set break gt_labels = data['gt_labels'] outputs = data['outputs'] gt_labels, outputs = lists_to_arrays([gt_labels, outputs]) print('Starting evaluate {}'.format(' and '.join(eval_metrics))) for eval_metric in eval_metrics: if eval_metric == 'mAP': mAP, APs = eval_map(outputs, gt_labels, None, print_summary=True) display_dict['APs_{:1d}'.format(i)] = APs elif eval_metric == 'multiple': metrics = [] for split, selected in dataset.class_split.items(): selected = list(selected) selected_outputs = outputs[:, selected] selected_gt_labels = gt_labels[:, selected] classes = np.asarray(dataset.CLASSES)[selected] mAP, APs = eval_map(selected_outputs, selected_gt_labels, classes, print_summary=False) micro_f1, macro_f1 = eval_F1(selected_outputs, selected_gt_labels) acc, per_cls_acc = eval_acc(selected_outputs, selected_gt_labels) metrics.append([split, mAP, micro_f1, macro_f1, acc]) mAP, APs = eval_map(outputs, gt_labels, dataset, print_summary=False) micro_f1, macro_f1 = eval_F1(outputs, gt_labels) acc, per_cls_acc = eval_acc(outputs, gt_labels) metrics.append(['Total', mAP, micro_f1, macro_f1, acc]) for split, mAP, micro_f1, macro_f1, acc in metrics: print( 'Split:{:>6s} mAP:{:.4f} acc:{:.4f} micro:{:.4f} macro:{:.4f}' .format(split, mAP, acc, micro_f1, macro_f1))