Пример #1
0
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)
Пример #2
0
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
Пример #3
0
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))