mmdetection
mmdetection copied to clipboard
Can't import L1Loss with fully qualified name mmdet.models.losses.smooth_l1_loss.L1Loss
When training a model using the Python-style configuration file. The configuration is saved within the checkpoint files, but all classes are replaced with their fully qualified names. For example, the L1Loss
is then replaced with mmdet.models.losses.smooth_l1_loss.L1Loss
.
Later, when we try to construct DetInferencer
the builder fails somewhere on Registry.get("mmdet.models.losses.smooth_l1_loss.L1Loss")
.
The problem doesn't occur for other classes, e.g. ResNet.
Reproduction
- What command or script did you run?
from mmengine.registry import MODELS
print(MODELS.get("mmdet.models.losses.L1Loss"))
print(MODELS.get("mmdet.models.losses.smooth_l1_loss.L1Loss"))
This outputs:
<class 'mmdet.models.losses.smooth_l1_loss.L1Loss'>
None
- Did you make any modifications on the code or config? Did you understand what you have modified?
This is raw minified example.
Environment
sys.platform: linux
Python: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
CUDA available: True
MUSA available: False
numpy_random_seed: 2147483648
GPU 0: Tesla T4
CUDA_HOME: /usr/local/cuda
NVCC: Cuda compilation tools, release 12.4, V12.4.99
PyTorch: 2.2.1+cu121
TorchVision: 0.17.1+cu121
OpenCV: 4.9.0
MMEngine: 0.10.3
MMDetection: 3.3.0+3da9cc6
Discussion
This is not necessarily an error by itself. It occurs, because inside mmdet/models/losses/__init__.py
we have:
from .smooth_l1_loss import L1Loss, SmoothL1Loss, l1_loss, smooth_l1_loss
The losses.smooth_l1_loss
module is hidden by losses.smooth_l1_loss.smooth_l1_loss
function. It's difficult to judge whether in this case mmdet.models.losses.smooth_l1_loss.L1Loss
is still a correct path or not, but it is serialized like this with MMDetection, e.g. when using:
mmdet/configs/_base_/models/faster_rcnn_r50_fpn.py
So, the solution would be to either:
- Avoid hiding module names with other objects (here
smooth_l1_loss
module hidden by a function) - EASY - Change the way MMEngine's
Registry.get
resolves fully qualified names - HARD - Change the serialization method - No idea how
Workaround
As a temporary workaround you can simply use your original config.py
, rather then the one transpiled and saved to your work dir (next to the checkpoints).