Repository: open-mmlab/mmdetection

Issue:
Evaluation error on Dynamic-rcnn
Thanks for your error report and we appreciate it a lot.

**Checklist**
```
1. I have searched related issues but cannot get the expected help.
```

**Describe the bug**
```
When I test the results using the /tools/test.py, it reports AttributeError: 'NoneType' object has no attribute 'dynamic_rcnn'.
```

**Reproduction**
1. What command or script did you run?
```
./tools/dist_test.sh /configs/config.py /models/epoch_X.pth 4 --out /results/result.pkl --format-only --options "jsonfile_prefix=/results/result"
```
2. Did you make any modifications on the code or config? Did you understand what you have modified?
I just change the training dataset and training policy (learning rate, # of epochs)

3. What dataset did you use?
```
my private dataset.
```
**Environment**

1. Please run `python mmdet/utils/collect_env.py` to collect necessary environment infomation and paste it here.
```
python mmdet/utils/collect_env.py

sys.platform: linux
Python: 3.7.7 (default, Mar 23 2020, 22:36:06) [GCC 7.3.0]
CUDA available: True
CUDA_HOME: /usr/local/cuda
NVCC: Cuda compilation tools, release 10.1, V10.1.243
GPU 0,1,2,3: Tesla V100-PCIE-16GB
GCC: gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
PyTorch: 1.5.0
PyTorch compiling details: PyTorch built with:
  - GCC 7.3
  - C++ Version: 201402
  - Intel(R) Math Kernel Library Version 2020.0.0 Product Build 20191122 for Intel(R) 64 architecture applications
  - Intel(R) MKL-DNN v0.21.1 (Git Hash 7d2fd500bc78936d1d648ca713b901012f470dbc)
  - OpenMP 201511 (a.k.a. OpenMP 4.5)
  - NNPACK is enabled
  - CPU capability usage: AVX2
  - CUDA Runtime 10.1
  - NVCC architecture flags: -gencode;arch=compute_37,code=sm_37;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_61,code=sm_61;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,code=sm_75;-gencode;arch=compute_37,code=compute_37
  - CuDNN 7.6.3
  - Magma 2.5.2
  - Build settings: BLAS=MKL, BUILD_TYPE=Release, CXX_FLAGS= -Wno-deprecated -fvisibility-inlines-hidden -fopenmp -DNDEBUG -DUSE_FBGEMM -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -DUSE_INTERNAL_THREADPOOL_IMPL -O2 -fPIC -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Wno-stringop-overflow, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, PERF_WITH_AVX512=1, USE_CUDA=ON, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=ON, USE_NNPACK=ON, USE_OPENMP=ON, USE_STATIC_DISPATCH=OFF, 

TorchVision: 0.6.0a0+82fd1c8
OpenCV: 4.2.0
MMCV: 0.6.2
MMDetection: 2.1.0+08d5892
MMDetection Compiler: GCC 7.4
MMDetection CUDA Compiler: 10.1
```
**Error traceback**
If applicable, paste the error trackback here.
```

Traceback (most recent call last):
  File "./tools/test.py", line 149, in <module>
    main()
  File "./tools/test.py", line 110, in main
    model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg)
  File "/mmdetection/mmdet/models/builder.py", line 67, in build_detector
    return build(cfg, DETECTORS, dict(train_cfg=train_cfg, test_cfg=test_cfg))
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/detectors/faster_rcnn.py", line 24, in __init__
    pretrained=pretrained)
  File "/mmdetection/mmdet/models/detectors/two_stage.py", line 43, in __init__
    self.roi_head = build_head(roi_head)
  File "/mmdetection/mmdet/models/builder.py", line 57, in build_head
    return build(cfg, HEADS)
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/roi_heads/dynamic_roi_head.py", line 17, in __init__
    self.iou_topk = self.train_cfg.dynamic_rcnn.iou_topk
AttributeError: 'NoneType' object has no attribute 'dynamic_rcnn'
Traceback (most recent call last):
  File "./tools/test.py", line 149, in <module>
    main()
  File "./tools/test.py", line 110, in main
    model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg)
  File "/mmdetection/mmdet/models/builder.py", line 67, in build_detector
    return build(cfg, DETECTORS, dict(train_cfg=train_cfg, test_cfg=test_cfg))
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/detectors/faster_rcnn.py", line 24, in __init__
    pretrained=pretrained)
  File "/mmdetection/mmdet/models/detectors/two_stage.py", line 43, in __init__
    self.roi_head = build_head(roi_head)
  File "/mmdetection/mmdet/models/builder.py", line 57, in build_head
    return build(cfg, HEADS)
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/roi_heads/dynamic_roi_head.py", line 17, in __init__
    self.iou_topk = self.train_cfg.dynamic_rcnn.iou_topk
AttributeError: 'NoneType' object has no attribute 'dynamic_rcnn'
Traceback (most recent call last):
  File "./tools/test.py", line 149, in <module>
    main()
  File "./tools/test.py", line 110, in main
    model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg)
  File "/mmdetection/mmdet/models/builder.py", line 67, in build_detector
    return build(cfg, DETECTORS, dict(train_cfg=train_cfg, test_cfg=test_cfg))
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/detectors/faster_rcnn.py", line 24, in __init__
    pretrained=pretrained)
  File "/mmdetection/mmdet/models/detectors/two_stage.py", line 43, in __init__
    self.roi_head = build_head(roi_head)
  File "/mmdetection/mmdet/models/builder.py", line 57, in build_head
    return build(cfg, HEADS)
  File "/mmdetection/mmdet/models/builder.py", line 32, in build
    return build_from_cfg(cfg, registry, default_args)
  File "/opt/conda/lib/python3.7/site-packages/mmcv/utils/registry.py", line 167, in build_from_cfg
    return obj_cls(**args)
  File "/mmdetection/mmdet/models/roi_heads/dynamic_roi_head.py", line 17, in __init__
    self.iou_topk = self.train_cfg.dynamic_rcnn.iou_topk
AttributeError: 'NoneType' object has no attribute 'dynamic_rcnn'
```





Discussion:
The config `dynamic_rcnn` is not specified.
> The config `dynamic_rcnn` is not specified.

Thanks! I use the example config, does that mean I need to specify something else in the example config or?

Resolving patch:
diff --git a/mmdet/models/roi_heads/dynamic_roi_head.py b/mmdet/models/roi_heads/dynamic_roi_head.py
--- a/mmdet/models/roi_heads/dynamic_roi_head.py
+++ b/mmdet/models/roi_heads/dynamic_roi_head.py
@@ -14,13 +14,6 @@ class DynamicRoIHead(StandardRoIHead):
     def __init__(self, **kwargs):
         super(DynamicRoIHead, self).__init__(**kwargs)
         assert isinstance(self.bbox_head.loss_bbox, SmoothL1Loss)
-        self.iou_topk = self.train_cfg.dynamic_rcnn.iou_topk
-        self.beta_topk = self.train_cfg.dynamic_rcnn.beta_topk
-        self.update_iter_interval = \
-            self.train_cfg.dynamic_rcnn.update_iter_interval
-        # warm-up values for IoU and beta
-        self.initial_iou = self.train_cfg.dynamic_rcnn.initial_iou
-        self.initial_beta = self.train_cfg.dynamic_rcnn.initial_beta
         # the IoU history of the past `update_iter_interval` iterations
         self.iou_history = []
         # the beta history of the past `update_iter_interval` iterations
@@ -78,7 +71,8 @@ def forward_train(self,
                     gt_labels[i],
                     feats=[lvl_feat[i][None] for lvl_feat in x])
                 # record the `iou_topk`-th largest IoU in an image
-                iou_topk = min(self.iou_topk, len(assign_result.max_overlaps))
+                iou_topk = min(self.train_cfg.dynamic_rcnn.iou_topk,
+                               len(assign_result.max_overlaps))
                 ious, _ = torch.topk(assign_result.max_overlaps, iou_topk)
                 cur_iou.append(ious[-1].item())
                 sampling_results.append(sampling_result)
@@ -104,7 +98,8 @@ def forward_train(self,
                 losses.update(mask_results['loss_mask'])
 
         # update IoU threshold and SmoothL1 beta
-        if len(self.iou_history) % self.update_iter_interval == 0:
+        update_iter_interval = self.train_cfg.dynamic_rcnn.update_iter_interval
+        if len(self.iou_history) % update_iter_interval == 0:
             new_iou_thr, new_beta = self.update_hyperparameters()
 
         return losses
@@ -123,7 +118,8 @@ def _bbox_forward_train(self, x, sampling_results, gt_bboxes, gt_labels,
         pos_inds = bbox_targets[3][:, 0].nonzero().squeeze(1)
         num_pos = len(pos_inds)
         cur_target = bbox_targets[2][pos_inds, :2].abs().mean(dim=1)
-        beta_topk = min(self.beta_topk * num_imgs, num_pos)
+        beta_topk = min(self.train_cfg.dynamic_rcnn.beta_topk * num_imgs,
+                        num_pos)
         cur_target = torch.kthvalue(cur_target, beta_topk)[0].item()
         self.beta_history.append(cur_target)
         loss_bbox = self.bbox_head.loss(bbox_results['cls_score'],
@@ -141,12 +137,14 @@ def update_hyperparameters(self):
         Returns:
             tuple[float]: the updated `iou_thr` and `SmoothL1 beta`
         """
-        new_iou_thr = max(self.initial_iou, np.mean(self.iou_history))
+        new_iou_thr = max(self.train_cfg.dynamic_rcnn.initial_iou,
+                          np.mean(self.iou_history))
         self.iou_history = []
         self.bbox_assigner.pos_iou_thr = new_iou_thr
         self.bbox_assigner.neg_iou_thr = new_iou_thr
         self.bbox_assigner.min_pos_iou = new_iou_thr
-        new_beta = min(self.initial_beta, np.median(self.beta_history))
+        new_beta = min(self.train_cfg.dynamic_rcnn.initial_beta,
+                       np.median(self.beta_history))
         self.beta_history = []
         self.bbox_head.loss_bbox.beta = new_beta
         return new_iou_thr, new_beta


Test patch: