import inspect import warnings from functools import partial from torch import nn from registry import BACKBONES, HEADS, LOSSES, NECKS, NETWORKS # from mmcv.utils import Registry from mmengine.registry import Registry def is_str(x): """Whether the input is an string instance. Note: This method is deprecated since python 2 is no longer supported. """ return isinstance(x, str) def build_from_cfg(cfg, registry, default_args=None): """Build a module from config dict. Args: cfg (dict): Config dict. It should at least contain the key "type". registry (:obj:`Registry`): The registry to search the type from. default_args (dict, optional): Default initialization arguments. Returns: object: The constructed object. """ if not isinstance(cfg, dict): raise TypeError(f"cfg must be a dict, but got {type(cfg)}") if "type" not in cfg: raise KeyError(f'the cfg dict must contain the key "type", but got {cfg}') if not isinstance(registry, Registry): raise TypeError("registry must be an mmcv.Registry object, " f"but got {type(registry)}") if not (isinstance(default_args, dict) or default_args is None): raise TypeError("default_args must be a dict or None, " f"but got {type(default_args)}") args = cfg.copy() obj_type = args.pop("type") if is_str(obj_type): obj_cls = registry.get(obj_type) if obj_cls is None: raise KeyError(f"{obj_type} is not in the {registry.name} registry") elif inspect.isclass(obj_type): obj_cls = obj_type else: raise TypeError(f"type must be a str or valid type, but got {type(obj_type)}") if default_args is not None: for name, value in default_args.items(): args.setdefault(name, value) return obj_cls(**args) import collections from registry import PIPELINES class Compose(object): def __init__(self, transforms): assert isinstance(transforms, collections.abc.Sequence) self.transforms = [] for transform in transforms: if isinstance(transform, dict): transform = build_from_cfg(transform, PIPELINES) self.transforms.append(transform) elif callable(transform): self.transforms.append(transform) else: raise TypeError('transform must be callable or a dict') def __call__(self, data): for t in self.transforms: data = t(data) if data is None: return None return data def __repr__(self): format_string = self.__class__.__name__ + '(' for t in self.transforms: format_string += '\n' format_string += ' {0}'.format(t) format_string += '\n)' return format_string def build(cfg, registry, default_args=None): if isinstance(cfg, list): modules = [build_from_cfg(cfg_, registry, default_args) for cfg_ in cfg] return nn.Sequential(*modules) else: return build_from_cfg(cfg, registry, default_args) def build_backbone(cfg): return build(cfg, BACKBONES) def build_neck(cfg): return build(cfg, NECKS) def build_head(cfg): return build(cfg, HEADS) def build_loss(cfg): return build(cfg, LOSSES) def build_network(cfg, train_cfg=None, test_cfg=None): return build(cfg, NETWORKS, dict(train_cfg=train_cfg, test_cfg=test_cfg)) def build_pipelines(pipelines): return Compose(pipelines)