open-mmlab / mmdetection

OpenMMLab Detection Toolbox and Benchmark
https://mmdetection.readthedocs.io
Apache License 2.0
29.55k stars 9.46k forks source link

KeyError: 'XXX is not in the models registry' #10576

Open MR-hyj opened 1 year ago

MR-hyj commented 1 year ago

I created an empty project based on this repo:

│   main.py               # custom file
│
├───configs               # common directory
│       newnet.py         # custom file
│
└───models                # python package
    │   builder.py        # copied from mmdet repo
    │   __init__.py
    │
    ├───backbones         # python package
    │   │   resnet.py     # copied from mmdet repo
    │   │   __init__.py    
    │
    ├───detectors         # python package
    │   │   newnet.py     # custom file
    │   │   __init__.py
    │
    ├───utils             # python package
    │   │   res_layer.py  # copied from mmdet repo
    │   │   __init__.py

where the files labeled copied from mmdet repo are directly copied from this repo, while those labeled custom file are newly created.

My goal is to test the registry module, by designing a new detector, which consists of only a single backbone ResNet:

# detectors/newnet.py
from ..builder import DETECTORS, MODELS
from mmcv.runner import BaseModule

@DETECTORS.register_module()
class NewNet(BaseModule):

    def __init__(self, backbone, **kwargs):
        super(NewNet, self).__init__()

# detectors/__init__.py
from .newnet import NewNet

__all__ = [
    'NewNet'
]

# configs/newnet.py
model = dict(
    type='NewNet',
    backbone=dict(
        type='ResNet',
        depth=50,
        out_indices=(3, 4, 5),
    ),
)

Finally, in main.py:

# main.py
from mmdet.apis import init_detector
from mmcv import Config

config = Config.fromfile('configs/newnet.py')
model = init_detector(config, checkpoint=None, device='cpu')

I got this error by running python mian.py

  File "D:\program\Anaconda3\envs\python367_torch110\lib\site-packages\mmcv\utils\registry.py", line 234, in build
    return self.build_func(*args, **kwargs, registry=self)
  File "D:\program\Anaconda3\envs\python367_torch110\lib\site-packages\mmcv\cnn\builder.py", line 27, in build_model_from_cfg
    return build_from_cfg(cfg, registry, default_args)
  File "D:\program\Anaconda3\envs\python367_torch110\lib\site-packages\mmcv\utils\registry.py", line 59, in build_from_cfg
    f'{obj_type} is not in the {registry.name} registry')
KeyError: 'NewNet is not in the models registry'

it seems my NewNet is not registered properly, so I added some prints in main.py:

# main.py
from models import DETECTORS, BACKBONES

print(config)
print(DETECTORS)
print(BACKBONES)
"""
========= outputs ============

Config (path: configs/newnet.py): {'model': {'type': 'NewNet', 'backbone': {'type': 'ResNet', 'depth': 50, 'out_indices': (3, 4, 5)}}}
Registry(name=models, items={'ResNet': <class 'models.backbones.resnet.ResNet'>, 
                             'ResNetV1d': <class 'models.backbones.resnet.ResNetV1d'>, 
                             'NewNet': <class 'models.detectors.newnet.NewNet'>}
)
Registry(name=models, items={'ResNet': <class 'models.backbones.resnet.ResNet'>, 
                             'ResNetV1d': <class 'models.backbones.resnet.ResNetV1d'>, 
                             'NewNet': <class 'models.detectors.newnet.NewNet'>}
)

"""

It is weird that the outputs suggest the NewNet is registered. So I took a further step to debug mode to find:

# main.py
# in this line, the ${MODEL} Registry remains to be 
# Registry(name=models, items={'ResNet': <class 'models.backbones.resnet.ResNet'>, 
#                              'ResNetV1d': <class 'models.backbones.resnet.ResNetV1d'>, 
#                              'NewNet': <class 'models.detectors.newnet.NewNet'>}
# )
model = init_detector(config, checkpoint=None, device='cpu')

# mmdet/models/builder:58
# however, in this line, the ${MODEL} Registry turns to be like 
# Registry(name=models, items={'CSPDarknet': <class 'mmdet.models.backbones.csp_darknet.CSPDarknet'>, ....), 
# which containing 189 values.
return DETECTORS.build(
    cfg, default_args=dict(train_cfg=train_cfg, test_cfg=test_cfg))

How could the Registry content take such a sudden change? Moreover, this new project contains only two backbones (ResNet and ResNetv1d), and a custom detector NewNet, how could the Regsitry contains the original models like CSPDarknet ?

MR-hyj commented 1 year ago

I’ve located the problem. The program calls python_env/site-packages/mmdetection/mmcv/cnn/builder.py other than my_project/models/builder.py. After I moved NewNet to project mmdetection it works well. But does that mean if I were to design a new model, all modifications should be done directly on the source code of this repo mmdetection?