Registry¶
- class mmengine.registry.Registry(name, build_func=None, parent=None, scope=None, locations=[])[source]¶
A registry to map strings to classes or functions.
Registered object could be built from registry. Meanwhile, registered functions could be called from registry.
- Parameters:
name (str) – Registry name.
build_func (callable, optional) – A function to construct instance from Registry.
build_from_cfg()
is used if neitherparent
orbuild_func
is specified. Ifparent
is specified andbuild_func
is not given,build_func
will be inherited fromparent
. Defaults to None.parent (
Registry
, optional) – Parent registry. The class registered in children registry could be built from parent. Defaults to None.scope (str, optional) – The scope of registry. It is the key to search for children registry. If not specified, scope will be the name of the package where class is defined, e.g. mmdet, mmcls, mmseg. Defaults to None.
locations (list) – The locations to import the modules registered in this registry. Defaults to []. New in version 0.4.0.
Examples
>>> # define a registry >>> MODELS = Registry('models') >>> # registry the `ResNet` to `MODELS` >>> @MODELS.register_module() >>> class ResNet: >>> pass >>> # build model from `MODELS` >>> resnet = MODELS.build(dict(type='ResNet')) >>> @MODELS.register_module() >>> def resnet50(): >>> pass >>> resnet = MODELS.build(dict(type='resnet50'))
>>> # hierarchical registry >>> DETECTORS = Registry('detectors', parent=MODELS, scope='det') >>> @DETECTORS.register_module() >>> class FasterRCNN: >>> pass >>> fasterrcnn = DETECTORS.build(dict(type='FasterRCNN'))
>>> # add locations to enable auto import >>> DETECTORS = Registry('detectors', parent=MODELS, >>> scope='det', locations=['det.models.detectors']) >>> # define this class in 'det.models.detectors' >>> @DETECTORS.register_module() >>> class MaskRCNN: >>> pass >>> # The registry will auto import det.models.detectors.MaskRCNN >>> fasterrcnn = DETECTORS.build(dict(type='det.MaskRCNN'))
More advanced usages can be found at https://mmengine.readthedocs.io/en/latest/advanced_tutorials/registry.html.
- build(cfg, *args, **kwargs)[source]¶
Build an instance.
Build an instance by calling
build_func
.- Parameters:
cfg (dict) – Config dict needs to be built.
- Returns:
The constructed object.
- Return type:
Any
Examples
>>> from mmengine import Registry >>> MODELS = Registry('models') >>> @MODELS.register_module() >>> class ResNet: >>> def __init__(self, depth, stages=4): >>> self.depth = depth >>> self.stages = stages >>> cfg = dict(type='ResNet', depth=50) >>> model = MODELS.build(cfg)
- get(key)[source]¶
Get the registry record.
If key` represents the whole object name with its module information, for example, mmengine.model.BaseModel,
get
will directly return the class objectBaseModel
.Otherwise, it will first parse
key
and check whether it contains a scope name. The logic to search forkey
:key
does not contain a scope name, i.e., it is purely a module name like “ResNet”:get()
will search forResNet
from the current registry to its parent or ancestors until finding it.key
contains a scope name and it is equal to the scope of the current registry (e.g., “mmcls”), e.g., “mmcls.ResNet”:get()
will only search forResNet
in the current registry.key
contains a scope name and it is not equal to the scope of the current registry (e.g., “mmdet”), e.g., “mmcls.FCNet”: If the scope exists in its children,get()
will get “FCNet” from them. If not,get()
will first get the root registry and root registry call its ownget()
method.
- Parameters:
key (str) – Name of the registered item, e.g., the class name in string format.
- Returns:
Return the corresponding class if
key
exists, otherwise return None.- Return type:
Type or None
Examples
>>> # define a registry >>> MODELS = Registry('models') >>> # register `ResNet` to `MODELS` >>> @MODELS.register_module() >>> class ResNet: >>> pass >>> resnet_cls = MODELS.get('ResNet')
>>> # hierarchical registry >>> DETECTORS = Registry('detector', parent=MODELS, scope='det') >>> # `ResNet` does not exist in `DETECTORS` but `get` method >>> # will try to search from its parents or ancestors >>> resnet_cls = DETECTORS.get('ResNet') >>> CLASSIFIER = Registry('classifier', parent=MODELS, scope='cls') >>> @CLASSIFIER.register_module() >>> class MobileNet: >>> pass >>> # `get` from its sibling registries >>> mobilenet_cls = DETECTORS.get('cls.MobileNet')
- import_from_location()[source]¶
Import modules from the pre-defined locations in self._location.
- Return type:
None
- static infer_scope()[source]¶
Infer the scope of registry.
The name of the package where registry is defined will be returned.
- Returns:
The inferred scope name.
- Return type:
Examples
>>> # in mmdet/models/backbone/resnet.py >>> MODELS = Registry('models') >>> @MODELS.register_module() >>> class ResNet: >>> pass >>> # The scope of ``ResNet`` will be ``mmdet``.
- register_module(name=None, force=False, module=None)[source]¶
Register a module.
A record will be added to
self._module_dict
, whose key is the class name or the specified name, and value is the class itself. It can be used as a decorator or a normal function.- Parameters:
- Return type:
Examples
>>> backbones = Registry('backbone') >>> # as a decorator >>> @backbones.register_module() >>> class ResNet: >>> pass >>> backbones = Registry('backbone') >>> @backbones.register_module(name='mnet') >>> class MobileNet: >>> pass
>>> # as a normal function >>> class ResNet: >>> pass >>> backbones.register_module(module=ResNet)
- static split_scope_key(key)[source]¶
Split scope and key.
The first scope will be split from key.
- Returns:
The former element is the first scope of the key, which can be
None
. The latter is the remaining key.- Return type:
- Parameters:
key (str) –
Examples
>>> Registry.split_scope_key('mmdet.ResNet') 'mmdet', 'ResNet' >>> Registry.split_scope_key('ResNet') None, 'ResNet'
- switch_scope_and_registry(scope)[source]¶
Temporarily switch default scope to the target scope, and get the corresponding registry.
If the registry of the corresponding scope exists, yield the registry, otherwise yield the current itself.
Examples
>>> from mmengine.registry import Registry, DefaultScope, MODELS >>> import time >>> # External Registry >>> MMDET_MODELS = Registry('mmdet_model', scope='mmdet', >>> parent=MODELS) >>> MMCLS_MODELS = Registry('mmcls_model', scope='mmcls', >>> parent=MODELS) >>> # Local Registry >>> CUSTOM_MODELS = Registry('custom_model', scope='custom', >>> parent=MODELS) >>> >>> # Initiate DefaultScope >>> DefaultScope.get_instance(f'scope_{time.time()}', >>> scope_name='custom') >>> # Check default scope >>> DefaultScope.get_current_instance().scope_name custom >>> # Switch to mmcls scope and get `MMCLS_MODELS` registry. >>> with CUSTOM_MODELS.switch_scope_and_registry(scope='mmcls') as registry: >>> DefaultScope.get_current_instance().scope_name mmcls >>> registry.scope mmcls >>> # Nested switch scope >>> with CUSTOM_MODELS.switch_scope_and_registry(scope='mmdet') as mmdet_registry: >>> DefaultScope.get_current_instance().scope_name mmdet >>> mmdet_registry.scope mmdet >>> with CUSTOM_MODELS.switch_scope_and_registry(scope='mmcls') as mmcls_registry: >>> DefaultScope.get_current_instance().scope_name mmcls >>> mmcls_registry.scope mmcls >>> >>> # Check switch back to original scope. >>> DefaultScope.get_current_instance().scope_name custom