open-mmlab/mmdetection · error · TypeError

The num_classes must be a current number, if there is cross

Error message

The num_classes must be a current number, if there is cross entropy loss.

What it means

When loss_cls (cross-entropy) is configured in LinearReIDHead, num_classes must be an int because the classification layer needs a fixed class count. Passing a non-int num_classes (or leaving a default like None) raises this TypeError.

Source

Thrown at mmdet/models/reid/linear_reid_head.py:79

                               'install mmpretrain first.')
        super(LinearReIDHead, self).__init__(init_cfg=init_cfg)

        assert isinstance(topk, (int, tuple))
        if isinstance(topk, int):
            topk = (topk, )
        for _topk in topk:
            assert _topk > 0, 'Top-k should be larger than 0'
        self.topk = topk

        if loss_cls is None:
            if isinstance(num_classes, int):
                warnings.warn('Since cross entropy is not set, '
                              'the num_classes will be ignored.')
            if loss_triplet is None:
                raise ValueError('Please choose at least one loss in '
                                 'triplet loss and cross entropy loss.')
        elif not isinstance(num_classes, int):
            raise TypeError('The num_classes must be a current number, '
                            'if there is cross entropy loss.')
        self.loss_cls = MODELS.build(loss_cls) if loss_cls else None
        self.loss_triplet = MODELS.build(loss_triplet) \
            if loss_triplet else None

        self.num_fcs = num_fcs
        self.in_channels = in_channels
        self.fc_channels = fc_channels
        self.out_channels = out_channels
        self.norm_cfg = norm_cfg
        self.act_cfg = act_cfg
        self.num_classes = num_classes

        self._init_layers()

    def _init_layers(self):
        """Initialize fc layers."""
        self.fcs = nn.ModuleList()

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Set num_classes to the integer number of tracklet identities (e.g. 751 for MOT17-half)
  2. If training triplet-only, remove loss_cls and keep num_classes omitted (a warning notes it is ignored)

Example fix

# before
head=dict(type='LinearReIDHead', loss_cls=dict(type='CrossEntropyLoss'))
# after
head=dict(type='LinearReIDHead', num_classes=751, loss_cls=dict(type='CrossEntropyLoss'))
Defensive patterns

Strategy: type-guard

Validate before calling

if head_cfg.get('loss_cls') is not None:
    assert isinstance(head_cfg.get('num_classes'), int), 'num_classes int required with loss_cls'

Type guard

def valid_reid_head_cfg(c: dict) -> bool: return c.get('loss_cls') is None or isinstance(c.get('num_classes'), int)

Prevention

When it happens

Trigger: head=dict(type='LinearReIDHead', loss_cls=dict(type='CrossEntropyLoss'), num_classes=None) or num_classes as a string/tuple while cross-entropy is enabled.

Common situations: Copy-pasted ReID configs where num_classes was removed for triplet-only training but loss_cls kept; dataset reid_classes not injected into the head variable.

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/d4ea2f67598104a8. Report an issue: GitHub.