Shortcuts

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 neither parent or build_func is specified. If parent is specified and build_func is not given, build_func will be inherited from parent. 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 object BaseModel.

Otherwise, it will first parse key and check whether it contains a scope name. The logic to search for key:

  • key does not contain a scope name, i.e., it is purely a module name like “ResNet”: get() will search for ResNet 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 for ResNet 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 own get() 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:

str

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:
  • name (str or list of str, optional) – The module name to be registered. If not specified, the class name will be used.

  • force (bool) – Whether to override an existing class with the same name. Defaults to False.

  • module (type, optional) – Module class or function to be registered. Defaults to None.

Return type:

type | Callable

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:

tuple[str | None, str]

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.

Parameters:

scope (str, optional) – The target scope.

Return type:

Generator

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