WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError

num_classes should be None when mask_predictor is specified

Error message

num_classes should be None when mask_predictor is specified

What it means

MaskRCNN's constructor lets you either supply a pre-built mask_predictor head or configure the head from num_classes, but not both. When a custom mask_predictor is provided, num_classes must be None because the predictor already defines its output dimensions; passing both is an unresolvable configuration conflict the library detects and raises as ValueError.

Source

Thrown at pytorch_object_detection/mask_rcnn/network_files/mask_rcnn.py:144

            box_fg_iou_thresh=0.5,
            box_bg_iou_thresh=0.5,
            box_batch_size_per_image=512,
            box_positive_fraction=0.25,
            bbox_reg_weights=None,
            # Mask parameters
            mask_roi_pool=None,
            mask_head=None,
            mask_predictor=None,
    ):

        if not isinstance(mask_roi_pool, (MultiScaleRoIAlign, type(None))):
            raise TypeError(
                f"mask_roi_pool should be of type MultiScaleRoIAlign or None instead of {type(mask_roi_pool)}"
            )

        if num_classes is not None:
            if mask_predictor is not None:
                raise ValueError("num_classes should be None when mask_predictor is specified")

        out_channels = backbone.out_channels

        if mask_roi_pool is None:
            mask_roi_pool = MultiScaleRoIAlign(featmap_names=["0", "1", "2", "3"], output_size=14, sampling_ratio=2)

        if mask_head is None:
            mask_layers = (256, 256, 256, 256)
            mask_dilation = 1
            mask_head = MaskRCNNHeads(out_channels, mask_layers, mask_dilation)

        if mask_predictor is None:
            mask_predictor_in_channels = 256
            mask_dim_reduced = 256
            mask_predictor = MaskRCNNPredictor(mask_predictor_in_channels, mask_dim_reduced, num_classes)

        super().__init__(
            backbone,

View on GitHub (pinned to 1ec3fe6f37)

Solutions

  1. Set num_classes=None when passing a mask_predictor
  2. Ensure the custom mask_predictor itself outputs the desired number of classes (its final conv out_channels)
  3. If you actually want the library to build the head, pass mask_predictor=None and keep num_classes

Example fix

// before
model = MaskRCNN(backbone, num_classes=91, mask_predictor=my_predictor)
// after
model = MaskRCNN(backbone, num_classes=None, mask_predictor=my_predictor)
Defensive patterns

Strategy: validation

Validate before calling

assert not (mask_predictor is not None and num_classes is not None), "pass either num_classes or mask_predictor, not both"
model = MaskRCNN(backbone, num_classes=num_classes if mask_predictor is None else None, mask_predictor=mask_predictor)

Type guard

def is_maskrcnn_cfg_valid(num_classes, mask_predictor):
    return mask_predictor is None or num_classes is None

Prevention

When it happens

Trigger: Calling MaskRCNN(...) with both a non-None mask_predictor and a non-None num_classes, e.g. MaskRCNN(backbone, num_classes=91, mask_predictor=MyPredictor(...)).

Common situations: Swapping in a custom mask head while leaving the tutorial num_classes argument in place; copying torchvision example code and modifying only the predictor; confusion after fine-tuning on a custom dataset.

Related errors


AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30). Data as JSON: /api/errors/63728d7ecf709b1d. Report an issue: GitHub.