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 suchView on GitHub (pinned to cfd5d3a985)
Solutions
- Set rpn_head.num_classes = 1 (or omit it — default is 1) in your config
- 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
- Never copy dataset num_classes into rpn_head
- Only roi_head.bbox_head carries dataset class counts
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
- The `num_classes` should be 1 in RPN, but get {rpn_head_num_
- Invalid text mode "{self.text_mode}".
- The type of frame_range must be int or list.
- results does not contain masks.
- {metric} is not in results
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/cd2dbb84e8ae3341.
Report an issue: GitHub.