Skip to content
Snippets Groups Projects
Unverified Commit 7e123ad6 authored by Zaida Zhou's avatar Zaida Zhou Committed by GitHub
Browse files

[Docs] Refine registry documentation (#186)

* [Docs] Refine registry documentation

* reslove comments

* minor refinement
parent a3b8d4ea
No related branches found
No related tags found
No related merge requests found
......@@ -262,7 +262,7 @@ class RetinaNet(nn.Module):
![registry](https://user-images.githubusercontent.com/58739961/153880947-1d66ac06-e5ee-448e-8d7d-201e96d1101d.png)
我们可以在 `MMDetection` 中调用 `MMEngine` 中模块。
我们可以在 `MMDetection` 中调用 `MMEngine`模块。
```python
from mmdet.models import MODELS
......@@ -278,6 +278,29 @@ model = MODELS.build(cfg=dict(type='Conv2d'))
如果不加前缀,`build` 方法首先查找当前节点是否存在该模块,如果存在则返回该模块,否则会继续向上查找父节点甚至祖先节点直到找到该模块,因此,如果当前节点和父节点存在同一模块并且希望调用父节点的模块,我们需要指定 `scope` 前缀。需要注意的是,向上查找父节点甚至祖先节点的**前提是父节点或者祖先节点的模块已通过某种方式被导入进而完成注册**。例如,在上面这个示例中,之所以没有显示导入父节点 `mmengine` 中的 `MODELS`,是因为通过 `from mmdet.models import MODELS` 间接触发 `mmengine.MODELS` 完成模块的注册。
上面展示了如何使用子节点注册器构建模块,但有时候我们希望不填加前缀也能在父节点注册器中构建子节点的模块,目的是提供通用的代码,避免下游算法库重复造轮子,该如何实现呢?
假设 MMEngine 中有一个 `build_model` 函数,该方法用于构建模型。
```python
from mmengine.registry import MODELS
def build_model(cfg):
model = MODELS.build(cfg)
```
如果我们希望在 MMDetection 中调用该函数构建 MMDetection 注册的模块,那么我们需要先获取一个 scope_name 为 'mmdet' 的 [DefaultScope](https://mmengine.readthedocs.io/zh/latest/api.html#mmengine.registry.DefaultScope) 实例,该实例全局唯一。
```python
from mmengine import build_model
import mmdet.models # 通过 import 的方式将 mmdet 中的模块导入注册器进而完成注册
default_scope = DefaultScope.get_instance('my_experiment', scope_name='mmdet')
model = build_model(cfg=dict(type='RetinaNet'))
```
获取 `DefaultScope` 实例的目的是使 Registry 的 build 方法会将 DefaultScope 名称(mmdet)注册器节点作为注册器的起点,才能在配置中不填加 mmdet 前缀的情况下在 MMDetection 的注册器节点中找到 RetinaNet 模块,如若不然,程序会报找不到 RetinaNet 错误。
### 调用兄弟节点的模块
除了可以调用父节点的模块,也可以调用兄弟节点的模块。
......@@ -311,16 +334,7 @@ from mmcls.models import MODELS
model = MODELS.build(cfg=dict(type='mmdet.RetinaNet'))
```
调用非本节点的模块需要指定在 `type` 中指定 `scope` 前缀,如果不想指定,我们可以创建一个全局变量 `default_scope` 并将 `scope_name` 设置为 'mmdet',`Registry` 会将 `scope_name` 对应的 `registry` 作为当前 `Registry` 并调用 `build` 方法。
```python
from mmengine.registry import DefaultScope, MODELS
# 调用注册在 mmdet 中的 RetinaNet
default_scope = DefaultScope.get_instance(
'my_experiment', scope_name='mmdet')
model = MODELS.build(cfg=dict(type='RetinaNet'))
```
调用非本节点或父节点的模块需要在 `type` 中指定 `scope` 前缀。
注册器除了支持两层结构,三层甚至更多层结构也是支持的。
......@@ -358,10 +372,4 @@ model = MODELS.build(cfg=dict(type='mmcls.ResNet'))
from mmcls.models import MODELS
# 需要注意前缀的顺序,'detplus.mmdet.ResNet' 是不正确的
model = MODELS.build(cfg=dict(type='mmdet.detplus.MetaNet'))
# 如果希望默认从 detplus 构建模型,设置可以 default_scope
from mmengine.registry import DefaultScope
default_scope = DefaultScope.get_instance(
'my_experiment', scope_name='detplus')
model = MODELS.build(cfg=dict(type='MetaNet', default_scope='detplus'))
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment