open-mmlab/mmdetection · warning

The `num_classes` should be 1 in RPN, but get {rpn_head_num_

Error message

The `num_classes` should be 1 in RPN, but get {rpn_head_num_classes}, please set rpn_head.num_classes = 1 in your config file.

What it means

RPN constructor warns when rpn_head config sets num_classes != 1, then force-sets it to 1. RPN is class-agnostic by design (objectness only), so any other value is a config mistake.

Source

Thrown at mmdet/models/detectors/rpn.py:48

    """

    def __init__(self,
                 backbone: ConfigType,
                 neck: ConfigType,
                 rpn_head: ConfigType,
                 train_cfg: ConfigType,
                 test_cfg: ConfigType,
                 data_preprocessor: OptConfigType = None,
                 init_cfg: OptMultiConfig = None,
                 **kwargs) -> None:
        super(SingleStageDetector, self).__init__(
            data_preprocessor=data_preprocessor, init_cfg=init_cfg)
        self.backbone = MODELS.build(backbone)
        self.neck = MODELS.build(neck) if neck is not None else None
        rpn_train_cfg = train_cfg['rpn'] if train_cfg is not None else None
        rpn_head_num_classes = rpn_head.get('num_classes', 1)
        if rpn_head_num_classes != 1:
            warnings.warn('The `num_classes` should be 1 in RPN, but get '
                          f'{rpn_head_num_classes}, please set '
                          'rpn_head.num_classes = 1 in your config file.')
            rpn_head.update(num_classes=1)
        rpn_head.update(train_cfg=rpn_train_cfg)
        rpn_head.update(test_cfg=test_cfg['rpn'])
        self.bbox_head = MODELS.build(rpn_head)
        self.train_cfg = train_cfg
        self.test_cfg = test_cfg

    def loss(self, batch_inputs: Tensor,
             batch_data_samples: SampleList) -> dict:
        """Calculate losses from a batch of inputs and data samples.

        Args:
            batch_inputs (Tensor): Input images of shape (N, C, H, W).
                These should usually be mean centered and std scaled.
            batch_data_samples (list[:obj:`DetDataSample`]): The batch
                data samples. It usually includes information such

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Set rpn_head.num_classes = 1 (or omit it — default is 1) in your config
  2. Leave num_classes for dataset classes on the roi_head's bbox_head only

Example fix

# before
rpn_head=dict(num_classes=80, ...)
# after
rpn_head=dict(num_classes=1, ...)  # or omit num_classes
Defensive patterns

Strategy: validation

Validate before calling

rpn = cfg['model']['rpn_head']
rpn['num_classes'] = 1  # RPN is class-agnostic
assert rpn.get('num_classes', 1) == 1

Prevention

When it happens

Trigger: Building an RPN detector with rpn_head=dict(..., num_classes=80) in the config.

Common situations: Users copy a detector bbox_head config (with dataset num_classes) into the rpn_head section; adapting two-stage configs and forgetting RPN semantics.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/cd2dbb84e8ae3341. Report an issue: GitHub.