Spaces:
Build error
Build error
| # -------------------------------------------------------- | |
| # X-Decoder -- Generalized Decoding for Pixel, Image, and Language | |
| # Copyright (c) 2022 Microsoft | |
| # Licensed under The MIT License [see LICENSE for details] | |
| # Modified by Xueyan Zou (xueyan@cs.wisc.edu) | |
| # -------------------------------------------------------- | |
| # Copyright (c) Facebook, Inc. and its affiliates. | |
| import os | |
| import numpy as np | |
| import itertools | |
| import logging | |
| from typing import Any, Callable, Dict, List, Optional, Union | |
| import torch | |
| import torch.utils.data | |
| import torch.utils.data as torchdata | |
| import detectron2.utils.comm as comm | |
| from detectron2.data.build import ( | |
| build_batch_data_loader, | |
| load_proposals_into_dataset, | |
| trivial_batch_collator, | |
| ) | |
| from detectron2.data import MetadataCatalog | |
| from detectron2.data.catalog import DatasetCatalog | |
| from detectron2.data.common import DatasetFromList, MapDataset | |
| from detectron2.data.dataset_mapper import DatasetMapper | |
| from detectron2.data.samplers import InferenceSampler, TrainingSampler | |
| from detectron2.evaluation import ( | |
| CityscapesInstanceEvaluator, | |
| CityscapesSemSegEvaluator, | |
| COCOEvaluator, | |
| DatasetEvaluators, | |
| LVISEvaluator, | |
| verify_results, | |
| ) | |
| from fvcore.common.config import CfgNode | |
| from .dataset_mappers import * | |
| from .evaluation import (InstanceSegEvaluator, | |
| ClassificationEvaluator, | |
| SemSegEvaluator, | |
| RetrievalEvaluator, | |
| #CaptioningEvaluator, | |
| COCOPanopticEvaluator, | |
| GroundingEvaluator, | |
| InteractiveEvaluator, | |
| ) | |
| from modeling.utils import configurable | |
| from utilities.distributed import get_world_size | |
| class JointLoader(torchdata.IterableDataset): | |
| """ | |
| Randomly sampple from one of the dataloaders per worker in each iteration. | |
| The sampling probability is determined by the size of each dataset. | |
| All examples from one worker (GPU) are from the same dataset in the iteration. | |
| Mixing is achieved through multiple workers (GPUs). | |
| """ | |
| def __init__(self, loaders, key_dataset, sample_prob, mixing_level): | |
| dataset_names = [] | |
| for key, loader in loaders.items(): | |
| name = "{}".format(key.split('_')[0]) | |
| setattr(self, name, loader) | |
| dataset_names += [name] | |
| self.dataset_names = dataset_names | |
| self.key_dataset = key_dataset | |
| if sample_prob == 'prop': | |
| self.sample_prob = [len(getattr(self, key)) for key in self.dataset_names] | |
| elif sample_prob == 'equal': | |
| self.sample_prob = [1 for key in self.dataset_names] | |
| elif sample_prob == 'sqrt': | |
| self.sample_prob = [np.sqrt(len(getattr(self, key))) for key in self.dataset_names] | |
| self.sample_prob = [p/sum(self.sample_prob) for p in self.sample_prob] | |
| self.mixing_level = mixing_level | |
| # Not sure how expensive `len(getattr(self, name))` is. computing this once and cache. | |
| # this assumes the len of the underlying data loaders do not change. | |
| self._len = sum(len(getattr(self, name)) for name in self.dataset_names) | |
| def __iter__(self): | |
| # Reset iterators at the start of each new epoch | |
| self.iterators = {name: iter(getattr(self, name)) for name in self.dataset_names} | |
| self._count = 0 | |
| return self | |
| def __next__(self): | |
| while self._count < self._len: | |
| # Randomly select a dataloader | |
| name = np.random.choice(self.dataset_names, size=None, replace=False, p=self.sample_prob) | |
| iterator = self.iterators[name] | |
| try: | |
| # Get next batch from the selected dataloader | |
| self._count += 1 | |
| return next(iterator) | |
| except StopIteration: | |
| # If the selected dataloader is exhausted, reinitialize it | |
| self.iterators[name] = iter(getattr(self, name)) | |
| raise StopIteration | |
| def __len__(self): | |
| return self._len | |
| def filter_images_with_only_crowd_annotations(dataset_dicts, dataset_names): | |
| """ | |
| Filter out images with none annotations or only crowd annotations | |
| (i.e., images without non-crowd annotations). | |
| A common training-time preprocessing on COCO dataset. | |
| Args: | |
| dataset_dicts (list[dict]): annotations in Detectron2 Dataset format. | |
| Returns: | |
| list[dict]: the same format, but filtered. | |
| """ | |
| num_before = len(dataset_dicts) | |
| def valid(anns): | |
| for ann in anns: | |
| if isinstance(ann, list): | |
| for instance in ann: | |
| if instance.get("iscrowd", 0) == 0: | |
| return True | |
| else: | |
| if ann.get("iscrowd", 0) == 0: | |
| return True | |
| return False | |
| dataset_dicts = [x for x in dataset_dicts if valid(x["annotations"])] | |
| num_after = len(dataset_dicts) | |
| logger = logging.getLogger(__name__) | |
| logger.info( | |
| "Removed {} images with no usable annotations. {} images left.".format( | |
| num_before - num_after, num_after | |
| ) | |
| ) | |
| return dataset_dicts | |
| def get_detection_dataset_dicts( | |
| dataset_names, filter_empty=True, proposal_files=None | |
| ): | |
| """ | |
| Load and prepare dataset dicts for instance detection/segmentation and semantic segmentation. | |
| Args: | |
| dataset_names (str or list[str]): a dataset name or a list of dataset names | |
| filter_empty (bool): whether to filter out images without instance annotations | |
| proposal_files (list[str]): if given, a list of object proposal files | |
| that match each dataset in `dataset_names`. | |
| Returns: | |
| list[dict]: a list of dicts following the standard dataset dict format. | |
| """ | |
| if isinstance(dataset_names, str): | |
| dataset_names = [dataset_names] | |
| assert len(dataset_names) | |
| dataset_dicts = [DatasetCatalog.get(dataset_name) for dataset_name in dataset_names] | |
| for dataset_name, dicts in zip(dataset_names, dataset_dicts): | |
| assert len(dicts), "Dataset '{}' is empty!".format(dataset_name) | |
| if proposal_files is not None: | |
| assert len(dataset_names) == len(proposal_files) | |
| # load precomputed proposals from proposal files | |
| dataset_dicts = [ | |
| load_proposals_into_dataset(dataset_i_dicts, proposal_file) | |
| for dataset_i_dicts, proposal_file in zip(dataset_dicts, proposal_files) | |
| ] | |
| dataset_dicts = list(itertools.chain.from_iterable(dataset_dicts)) | |
| has_instances = "annotations" in dataset_dicts[0] | |
| if filter_empty and has_instances: | |
| dataset_dicts = filter_images_with_only_crowd_annotations(dataset_dicts, dataset_names) | |
| assert len(dataset_dicts), "No valid data found in {}.".format(",".join(dataset_names)) | |
| return dataset_dicts | |
| def _test_loader_from_config(cfg, dataset_name, mapper=None): | |
| """ | |
| Uses the given `dataset_name` argument (instead of the names in cfg), because the | |
| standard practice is to evaluate each test set individually (not combining them). | |
| """ | |
| if isinstance(dataset_name, str): | |
| dataset_name = [dataset_name] | |
| dataset = get_detection_dataset_dicts( | |
| dataset_name, | |
| filter_empty=False, | |
| proposal_files=None, | |
| ) | |
| if mapper is None: | |
| mapper_cfg = CfgNode({'INPUT': cfg['INPUT'], 'MODEL': cfg['MODEL'], 'DATASETS': cfg['DATASETS']}) | |
| mapper = DatasetMapper(mapper_cfg, False) | |
| assert cfg['TEST']['BATCH_SIZE_TOTAL'] % get_world_size() == 0, "Evaluation total batchsize is not divisible by gpu number" | |
| #batch_size = cfg['TEST']['BATCH_SIZE_TOTAL'] // get_world_size() | |
| batch_size = 1 | |
| return { | |
| "dataset": dataset, | |
| "mapper": mapper, | |
| "num_workers": cfg['DATALOADER']['NUM_WORKERS'], | |
| "sampler": InferenceSampler(len(dataset)), | |
| "batch_size": batch_size, | |
| } | |
| def build_detection_test_loader( | |
| dataset: Union[List[Any], torchdata.Dataset], | |
| *, | |
| mapper: Callable[[Dict[str, Any]], Any], | |
| sampler: Optional[torchdata.Sampler] = None, | |
| batch_size: int = 1, | |
| num_workers: int = 0, | |
| collate_fn: Optional[Callable[[List[Any]], Any]] = None, | |
| ) -> torchdata.DataLoader: | |
| """ | |
| Similar to `build_detection_train_loader`, with default batch size = 1, | |
| and sampler = :class:`InferenceSampler`. This sampler coordinates all workers | |
| to produce the exact set of all samples. | |
| Args: | |
| dataset: a list of dataset dicts, | |
| or a pytorch dataset (either map-style or iterable). They can be obtained | |
| by using :func:`DatasetCatalog.get` or :func:`get_detection_dataset_dicts`. | |
| mapper: a callable which takes a sample (dict) from dataset | |
| and returns the format to be consumed by the model. | |
| When using cfg, the default choice is ``DatasetMapper(cfg, is_train=False)``. | |
| sampler: a sampler that produces | |
| indices to be applied on ``dataset``. Default to :class:`InferenceSampler`, | |
| which splits the dataset across all workers. Sampler must be None | |
| if `dataset` is iterable. | |
| batch_size: the batch size of the data loader to be created. | |
| Default to 1 image per worker since this is the standard when reporting | |
| inference time in papers. | |
| num_workers: number of parallel data loading workers | |
| collate_fn: same as the argument of `torch.utils.data.DataLoader`. | |
| Defaults to do no collation and return a list of data. | |
| Returns: | |
| DataLoader: a torch DataLoader, that loads the given detection | |
| dataset, with test-time transformation and batching. | |
| Examples: | |
| :: | |
| data_loader = build_detection_test_loader( | |
| DatasetRegistry.get("my_test"), | |
| mapper=DatasetMapper(...)) | |
| # or, instantiate with a CfgNode: | |
| data_loader = build_detection_test_loader(cfg, "my_test") | |
| """ | |
| if isinstance(dataset, list): | |
| dataset = DatasetFromList(dataset, copy=False) | |
| if mapper is not None: | |
| dataset = MapDataset(dataset, mapper) | |
| if isinstance(dataset, torchdata.IterableDataset): | |
| assert sampler is None, "sampler must be None if dataset is IterableDataset" | |
| else: | |
| if sampler is None: | |
| sampler = InferenceSampler(len(dataset)) | |
| return torchdata.DataLoader( | |
| dataset, | |
| batch_size=batch_size, | |
| sampler=sampler, | |
| drop_last=False, | |
| num_workers=num_workers, | |
| collate_fn=trivial_batch_collator if collate_fn is None else collate_fn, | |
| ) | |
| def _train_loader_from_config(cfg, dataset_name, mapper, *, dataset=None, sampler=None): | |
| cfg_datasets = cfg['DATASETS'] | |
| cfg_dataloader = cfg['DATALOADER'] | |
| if dataset is None: | |
| dataset = get_detection_dataset_dicts( | |
| dataset_name, | |
| filter_empty=cfg_dataloader['FILTER_EMPTY_ANNOTATIONS'], | |
| proposal_files=cfg_datasets['PROPOSAL_FILES_TRAIN'] if cfg_dataloader['LOAD_PROPOSALS'] else None, | |
| ) | |
| if mapper is None: | |
| mapper = DatasetMapper(cfg, True) | |
| if sampler is None: | |
| sampler_name = cfg_dataloader['SAMPLER_TRAIN'] | |
| logger = logging.getLogger(__name__) | |
| logger.info("Using training sampler {}".format(sampler_name)) | |
| sampler = TrainingSampler(len(dataset)) | |
| return { | |
| "dataset": dataset, | |
| "sampler": sampler, | |
| "mapper": mapper, | |
| "total_batch_size": cfg['TRAIN']['BATCH_SIZE_TOTAL'], | |
| "aspect_ratio_grouping": cfg_dataloader['ASPECT_RATIO_GROUPING'], | |
| "num_workers": cfg_dataloader['NUM_WORKERS'], | |
| } | |
| def build_detection_train_loader( | |
| dataset, *, mapper, sampler=None, total_batch_size, aspect_ratio_grouping=True, num_workers=0 | |
| ): | |
| """ | |
| Build a dataloader for object detection with some default features. | |
| This interface is experimental. | |
| Args: | |
| dataset (list or torch.utils.data.Dataset): a list of dataset dicts, | |
| or a map-style pytorch dataset. They can be obtained by using | |
| :func:`DatasetCatalog.get` or :func:`get_detection_dataset_dicts`. | |
| mapper (callable): a callable which takes a sample (dict) from dataset and | |
| returns the format to be consumed by the model. | |
| When using cfg, the default choice is ``DatasetMapper(cfg, is_train=True)``. | |
| sampler (torch.utils.data.sampler.Sampler or None): a sampler that | |
| produces indices to be applied on ``dataset``. | |
| Default to :class:`TrainingSampler`, which coordinates a random shuffle | |
| sequence across all workers. | |
| total_batch_size (int): total batch size across all workers. Batching | |
| simply puts data into a list. | |
| aspect_ratio_grouping (bool): whether to group images with similar | |
| aspect ratio for efficiency. When enabled, it requires each | |
| element in dataset be a dict with keys "width" and "height". | |
| num_workers (int): number of parallel data loading workers | |
| Returns: | |
| torch.utils.data.DataLoader: a dataloader. Each output from it is a | |
| ``list[mapped_element]`` of length ``total_batch_size / num_workers``, | |
| where ``mapped_element`` is produced by the ``mapper``. | |
| """ | |
| if isinstance(dataset, list): | |
| dataset = DatasetFromList(dataset, copy=False) | |
| if mapper is not None: | |
| dataset = MapDataset(dataset, mapper) | |
| if sampler is None: | |
| sampler = TrainingSampler(len(dataset)) | |
| assert isinstance(sampler, torch.utils.data.sampler.Sampler) | |
| return build_batch_data_loader( | |
| dataset, | |
| sampler, | |
| total_batch_size, | |
| aspect_ratio_grouping=aspect_ratio_grouping, | |
| num_workers=num_workers, | |
| ) | |
| def get_config_from_name(cfg, dataset_name): | |
| # adjust config according to dataset | |
| if 'refcoco' in dataset_name: | |
| cfg.update(cfg['REF']) | |
| return cfg | |
| elif 'cocomini' in dataset_name: | |
| cfg.update(cfg['DAVIS']) | |
| return cfg | |
| elif 'ytvos' in dataset_name: | |
| cfg.update(cfg['VOS']) | |
| return cfg | |
| elif 'ade600' in dataset_name: | |
| cfg.update(cfg['DAVIS']) | |
| return cfg | |
| elif 'openimage600' in dataset_name: | |
| cfg.update(cfg['DAVIS']) | |
| return cfg | |
| elif 'ade' in dataset_name: | |
| if 'ADE20K' in cfg.keys(): | |
| cfg.update(cfg['ADE20K']) | |
| return cfg | |
| elif 'imagenet' in dataset_name: | |
| if 'IMAGENET' in cfg.keys(): | |
| cfg.update(cfg['IMAGENET']) | |
| return cfg | |
| elif 'vlp' in dataset_name: | |
| cfg.update(cfg['VLP']) | |
| return cfg | |
| elif 'coco' in dataset_name: | |
| if 'COCO' in cfg.keys(): | |
| cfg.update(cfg['COCO']) | |
| return cfg | |
| elif 'voc' in dataset_name: | |
| cfg.update(cfg['VOC']) | |
| return cfg | |
| elif 'context' in dataset_name: | |
| cfg.update(cfg['CONTEXT']) | |
| return cfg | |
| elif 'sun' in dataset_name: | |
| cfg.update(cfg['SUN']) | |
| return cfg | |
| elif 'scan' in dataset_name: | |
| cfg.update(cfg['SCAN']) | |
| return cfg | |
| elif 'cityscape' in dataset_name: | |
| cfg.update(cfg['CITY']) | |
| return cfg | |
| elif 'bdd' in dataset_name: | |
| cfg.update(cfg['BDD']) | |
| return cfg | |
| elif 'tsv' in dataset_name: | |
| cfg.update(cfg['TSV']) | |
| return cfg | |
| elif 'phrasecut' in dataset_name: | |
| cfg.update(cfg['PHRASE']) | |
| return cfg | |
| elif 'object365' in dataset_name: | |
| cfg.update(cfg['OBJECT365']) | |
| return cfg | |
| elif 'openimage' in dataset_name: | |
| cfg.update(cfg['OPENIMAGE']) | |
| return cfg | |
| elif 'lvis' in dataset_name: | |
| cfg.update(cfg['LVIS']) | |
| return cfg | |
| elif 'seginw' in dataset_name: | |
| cfg.update(cfg['SEGINW']) | |
| return cfg | |
| elif 'sbd' in dataset_name: | |
| cfg.update(cfg['SBD']) | |
| return cfg | |
| elif 'davis' in dataset_name: | |
| cfg.update(cfg['DAVIS']) | |
| return cfg | |
| elif 'med_sam' in dataset_name: | |
| cfg.update(cfg['MedSAM']) | |
| return cfg | |
| elif 'biomed' in dataset_name: | |
| cfg.update(cfg['BioMed']) | |
| return cfg | |
| elif 'sam' in dataset_name: | |
| cfg.update(cfg['SAM']) | |
| return cfg | |
| else: | |
| assert False, "dataset not support." | |
| def build_eval_dataloader(cfg, ): | |
| dataloaders = [] | |
| for dataset_name in cfg['DATASETS']['TEST']: | |
| cfg = get_config_from_name(cfg, dataset_name) | |
| # adjust mapper according to dataset | |
| if dataset_name == 'imagenet_val': | |
| mapper = ImageNetDatasetMapper(cfg, False) | |
| elif dataset_name == 'bdd10k_val_sem_seg': | |
| mapper = BDDSemDatasetMapper(cfg, False) | |
| elif dataset_name in ["vlp_val", "vlp_captioning_val", "vlp_val2017", "vlp_captioning_val2017"]: | |
| mapper = VLPreDatasetMapper(cfg, False, dataset_name) | |
| elif dataset_name in ["scannet_21_val_seg", "scannet_38_val_seg", "scannet_41_val_seg"]: | |
| mapper = ScanNetSegDatasetMapper(cfg, False) | |
| elif dataset_name in ["scannet_21_panoptic_val", 'bdd10k_40_panoptic_val']: | |
| mapper = ScanNetPanoDatasetMapper(cfg, False) | |
| elif "pascalvoc_val" in dataset_name: | |
| mapper = PascalVOCSegDatasetMapperIX(cfg, False, dataset_name) | |
| elif 'sun' in dataset_name: | |
| mapper = SunRGBDSegDatasetMapper(cfg, False) | |
| elif 'refcoco' in dataset_name: | |
| mapper = RefCOCODatasetMapper(cfg, False) | |
| elif 'med_sam' in dataset_name: | |
| mapper = MedSAMDatasetMapper(cfg, False) | |
| elif 'biomed' in dataset_name: | |
| mapper = BioMedDatasetMapper(cfg, False) | |
| else: | |
| mapper = None | |
| dataloaders += [build_detection_test_loader(cfg, dataset_name, mapper=mapper)] | |
| return dataloaders | |
| def build_train_dataloader(cfg, ): | |
| dataset_names = cfg['DATASETS']['TRAIN'] | |
| loaders = {} | |
| for dataset_name in dataset_names: | |
| cfg = get_config_from_name(cfg, dataset_name) | |
| mapper_name = cfg['INPUT']['DATASET_MAPPER_NAME'] | |
| # Semantic segmentation dataset mapper | |
| if mapper_name == "mask_former_semantic": | |
| mapper = MaskFormerSemanticDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| # Panoptic segmentation dataset mapper | |
| elif mapper_name == "mask_former_panoptic": | |
| mapper = MaskFormerPanopticDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| # Instance segmentation dataset mapper | |
| elif mapper_name == "mask_former_instance": | |
| mapper = MaskFormerInstanceDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| # coco instance segmentation lsj new baseline | |
| elif mapper_name == "coco_instance_lsj": | |
| mapper = COCOInstanceNewBaselineDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| # coco panoptic segmentation lsj new baseline | |
| elif mapper_name == "coco_panoptic_lsj": | |
| mapper = COCOPanopticNewBaselineDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| elif mapper_name == "vlpretrain": | |
| mapper = VLPreDatasetMapper(cfg, True, dataset_name) | |
| loaders['vlp'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| elif mapper_name == "refcoco": | |
| mapper = RefCOCODatasetMapper(cfg, True) | |
| loaders['ref'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| elif mapper_name == "coco_interactive": | |
| mapper = COCOPanopticInteractiveDatasetMapper(cfg, True) | |
| loaders['coco'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| elif mapper_name == "medsam_interactive": | |
| mapper = MedSAMDatasetMapper(cfg, True) | |
| loaders['med_sam'] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| elif mapper_name == "biomed_interactive": | |
| mapper = BioMedDatasetMapper(cfg, True) | |
| name_key = dataset_name.split("_")[1] | |
| loaders[name_key] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| else: | |
| mapper = None | |
| loaders[dataset_name] = build_detection_train_loader(cfg, dataset_name=dataset_name, mapper=mapper) | |
| if len(loaders) == 1 or not cfg['LOADER'].get('JOINT', False): | |
| return list(loaders.values())[0] | |
| else: | |
| sample_prob = cfg['LOADER'].get('SAMPLE_PROB', 'prop') | |
| mixing_level = cfg['LOADER'].get('MIXING_LEVEL', 1) | |
| return JointLoader(loaders, key_dataset=cfg['LOADER'].get('KEY_DATASET', 'coco'), sample_prob=sample_prob, mixing_level=mixing_level) | |
| def build_evaluator(cfg, dataset_name, output_folder=None): | |
| """ | |
| Create evaluator(s) for a given dataset. | |
| This uses the special metadata "evaluator_type" associated with each | |
| builtin dataset. For your own dataset, you can simply create an | |
| evaluator manually in your script and do not have to worry about the | |
| hacky if-else logic here. | |
| """ | |
| if output_folder is None: | |
| output_folder = os.path.join(cfg["SAVE_DIR"], "inference") | |
| evaluator_list = [] | |
| evaluator_type = MetadataCatalog.get(dataset_name).evaluator_type | |
| # semantic segmentation | |
| if evaluator_type in ["sem_seg", "ade20k_panoptic_seg"]: | |
| evaluator_list.append( | |
| SemSegEvaluator( | |
| dataset_name, | |
| distributed=True, | |
| output_dir=output_folder, | |
| ) | |
| ) | |
| # instance segmentation | |
| if evaluator_type == "coco": | |
| evaluator_list.append(COCOEvaluator(dataset_name, output_dir=output_folder)) | |
| cfg_model_decoder_test = cfg["MODEL"]["DECODER"]["TEST"] | |
| # panoptic segmentation | |
| if evaluator_type in [ | |
| "coco_panoptic_seg", | |
| "ade20k_panoptic_seg", | |
| "cityscapes_panoptic_seg", | |
| "mapillary_vistas_panoptic_seg", | |
| "scannet_panoptic_seg", | |
| "bdd_panoptic_pano" | |
| ]: | |
| if cfg_model_decoder_test["PANOPTIC_ON"]: | |
| evaluator_list.append(COCOPanopticEvaluator(dataset_name, output_folder)) | |
| # COCO | |
| if (evaluator_type == "coco_panoptic_seg" and cfg_model_decoder_test["INSTANCE_ON"]) or evaluator_type == "object365_od": | |
| evaluator_list.append(COCOEvaluator(dataset_name, output_dir=output_folder)) | |
| if (evaluator_type == "coco_panoptic_seg" and cfg_model_decoder_test["SEMANTIC_ON"]) or evaluator_type == "coco_sem_seg": | |
| evaluator_list.append(SemSegEvaluator(dataset_name, distributed=True, output_dir=output_folder)) | |
| # Mapillary Vistas | |
| if evaluator_type == "mapillary_vistas_panoptic_seg" and cfg_model_decoder_test["INSTANCE_ON"]: | |
| evaluator_list.append(InstanceSegEvaluator(dataset_name, output_dir=output_folder)) | |
| if evaluator_type == "mapillary_vistas_panoptic_seg" and cfg_model_decoder_test["SEMANTIC_ON"]: | |
| evaluator_list.append(SemSegEvaluator(dataset_name, distributed=True, output_dir=output_folder)) | |
| # Cityscapes | |
| if evaluator_type == "cityscapes_instance": | |
| assert ( | |
| torch.cuda.device_count() > comm.get_rank() | |
| ), "CityscapesEvaluator currently do not work with multiple machines." | |
| return CityscapesInstanceEvaluator(dataset_name) | |
| if evaluator_type == "cityscapes_sem_seg": | |
| assert ( | |
| torch.cuda.device_count() > comm.get_rank() | |
| ), "CityscapesEvaluator currently do not work with multiple machines." | |
| return CityscapesSemSegEvaluator(dataset_name) | |
| if evaluator_type == "cityscapes_panoptic_seg": | |
| if cfg_model_decoder_test["SEMANTIC_ON"]: | |
| assert ( | |
| torch.cuda.device_count() > comm.get_rank() | |
| ), "CityscapesEvaluator currently do not work with multiple machines." | |
| evaluator_list.append(CityscapesSemSegEvaluator(dataset_name)) | |
| if cfg_model_decoder_test["INSTANCE_ON"]: | |
| assert ( | |
| torch.cuda.device_count() > comm.get_rank() | |
| ), "CityscapesEvaluator currently do not work with multiple machines." | |
| evaluator_list.append(CityscapesInstanceEvaluator(dataset_name)) | |
| # ADE20K | |
| if evaluator_type == "ade20k_panoptic_seg" and cfg_model_decoder_test["INSTANCE_ON"]: | |
| evaluator_list.append(InstanceSegEvaluator(dataset_name, output_dir=output_folder)) | |
| # SEGINW | |
| if evaluator_type == "seginw" and cfg_model_decoder_test["INSTANCE_ON"]: | |
| evaluator_list.append(InstanceSegEvaluator(dataset_name, output_dir=output_folder)) | |
| # LVIS | |
| if evaluator_type == "lvis": | |
| return LVISEvaluator(dataset_name, output_dir=output_folder) | |
| # Classification | |
| if evaluator_type == "classification": | |
| evaluator_list.append(ClassificationEvaluator(dataset_name, output_folder)) | |
| # Retrieval | |
| if evaluator_type in ["retrieval"]: | |
| evaluator_list.append(RetrievalEvaluator(dataset_name, output_folder, cfg['MODEL']['DECODER']['RETRIEVAL']['ENSEMBLE'])) | |
| if evaluator_type == "captioning": | |
| evaluator_list.append(CaptioningEvaluator(dataset_name, output_folder, MetadataCatalog.get(dataset_name).gt_json)) | |
| if evaluator_type in ["grounding_refcoco", "grounding_phrasecut", "grounding_spatial", "grounding_entity"]: | |
| evaluator_list.append(GroundingEvaluator(dataset_name)) | |
| # Interactive | |
| if evaluator_type in ["interactive", "interactive_grounding"]: | |
| evaluator_list.append(InteractiveEvaluator(dataset_name, output_dir=output_folder, max_clicks=cfg['STROKE_SAMPLER']['EVAL']['MAX_ITER'], iou_iter=cfg['STROKE_SAMPLER']['EVAL']['IOU_ITER'])) | |
| if len(evaluator_list) == 0: | |
| raise NotImplementedError( | |
| "no Evaluator for the dataset {} with the type {}".format( | |
| dataset_name, evaluator_type | |
| ) | |
| ) | |
| elif len(evaluator_list) == 1: | |
| return evaluator_list[0] | |
| return DatasetEvaluators(evaluator_list) | |