Skip to content

Detectors & TABDet wrappers

DetectorPredParams(conf_threshold, nms_iou, max_det) dataclass

Bases: deepvisiontools.models.base.basemodel.BasePredParams

Prediction-time parameters for Detector decoding.

Controlled from global config
  • current().data_box.conf_threshold
  • current().data_box.nms_threshold
  • current().model_max_detection (fallback 500)

DetectorSegPredParams(conf_threshold, nms_iou, max_det, mask_threshold, apply_mask_scoring, use_soft_nms, soft_nms_method, soft_nms_sigma, soft_nms_iou_thresh, soft_nms_score_thresh) dataclass

Bases: deepvisiontools.models.base.basemodel.BasePredParams

Prediction-time parameters for Detector instance segmentation decoding.

Controlled from global config
  • current().data_instance_mask.conf_threshold
  • current().data_instance_mask.nms_threshold
  • current().data_instance_mask.mask_logits_threshold
  • current().model_max_detection (fallback 500)

Extra switches for Detectron/MMDet-style decoding: - use_soft_nms + params - apply_mask_scoring (Mask Scoring R-CNN)

Detector(cfg, *, cfg_yaml_text=None, cfg_yaml_source=None, cfg_zoo_key=None)

Bases: torch.nn.Module

Facade torch.nn.Module for Detector models. Detectors include several heads / necks. Detectors must preferably be built from yaml Note that detector are input size flexible only if using a CNN encoder.

Parameters:

Name Type Description Default
cfg deepvisiontools.models.detectors.models.config.config.DetectorCfg

dataclass that configures the detector.

required
cfg_yaml_text str | None, **optional**

Defaults to None.

None
cfg_yaml_source str | None, **optional**

Defaults to None.

None
cfg_zoo_key str | None, **optional**

Defaults to None.

None
Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
def __init__(
    self,
    cfg: DetectorCfg,
    *,
    cfg_yaml_text: str | None = None,
    cfg_yaml_source: str | None = None,
    cfg_zoo_key: str | None = None,
) -> None:

    super().__init__()

    from .....config import current  # local import avoids circulars

    def _is_instance_mask_head(name: str) -> bool:
        n = (name or "").lower()
        return ("mask" in n) or (n == "cascademaskrcnnhead")

    head_name = str(getattr(getattr(cfg, "head", None), "name", "") or "")

    if cfg.num_classes is not None:
        resolved_nc = int(cfg.num_classes)
    else:
        head_cfg_nc = getattr(cfg.head, "num_classes", None)
        if head_cfg_nc is not None:
            resolved_nc = int(head_cfg_nc)
        else:
            resolved_nc = int(
                current().data_instance_mask.num_classes
                if _is_instance_mask_head(head_name)
                else current().data_box.num_classes
            )

    cfg = replace(cfg, num_classes=resolved_nc)

    self.cfg = cfg
    self.cfg_yaml_text = cfg_yaml_text
    self.cfg_yaml_source = cfg_yaml_source
    self.cfg_zoo_key = cfg_zoo_key

    self.model = self._build_torch_model(cfg)

    # New: optional whole-model COCO pretrained load
    self._maybe_load_full_coco_pretrained()

    head_cfg = getattr(cfg, "head", None)
    head_name = str(getattr(head_cfg, "name", "") or "")
    append_gt = bool(getattr(head_cfg, "proposal_append_gt", False))
    self.requires_targets_in_train = (head_name == "CascadeRCNNHead") and append_gt

    resolved_loss = resolve_default_loss(
        head_name=str(getattr(cfg.head, "name", "")),
        explicit_loss=getattr(cfg.loss, "name", None),
    )
    self.loss = build_loss(
        self.model.head,
        cast(
            Literal["ATSS_VFNet", "CascadeRCNN", "CascadeMaskRCNN"],
            resolved_loss,
        ),
    )

    if self.cfg_yaml_text is None and hasattr(cfg, "export_to_yaml_text"):
        self.cfg_yaml_text = cfg.export_to_yaml_text()
        self.cfg_yaml_source = self.cfg_yaml_source or "cfg.export_to_yaml_text"

from_config(name, overrides=None) staticmethod

name can be: - a zoo key - a YAML file path - raw YAML text

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
@staticmethod
def from_config(name: str, overrides: Mapping[str, Any] | None = None) -> Detector:
    """
    `name` can be:
    - a zoo key
    - a YAML file path
    - raw YAML text
    """
    if isinstance(name, str) and os.path.exists(name) and os.path.isfile(name):
        return Detector.from_yaml(name, overrides=overrides)

    if isinstance(name, str) and ("\n" in name) and (":" in name):
        return Detector.from_yaml(name, overrides=overrides)

    if name not in _DETECTOR_CONFIGS:
        raise KeyError(
            f"Unknown Detector config '{name}'. "
            f"Expected one of {sorted(_DETECTOR_CONFIGS.keys())}, or a YAML file path, or YAML text."
        )

    stem = _DETECTOR_CONFIGS[name]
    yaml_text = load_zoo_yaml_text(stem)
    return Detector.from_yaml(
        yaml_text,
        overrides=overrides,
        _source_override=f"zoo:{name}",
        _zoo_key=name,
    )

from_yaml(source, overrides=None, _source_override=None, _zoo_key=None) staticmethod

Build from YAML file path or YAML text. Supports overrides.

Notes: - This method only parses YAML into cfg objects. - num_classes inference (top-level -> head -> dataset defaults) is handled centrally in Detector.__init__, so we do NOT resolve it here. - If YAML provides top-level num_classes, it is preserved. Otherwise it is left unset (None) and inferred later.

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
@staticmethod
def from_yaml(
    source: str | Path,
    overrides: Mapping[str, Any] | None = None,
    _source_override: str | None = None,
    _zoo_key: str | None = None,
) -> Detector:
    """
    Build from YAML file path or YAML text. Supports overrides.

    Notes:
    - This method only parses YAML into cfg objects.
    - `num_classes` inference (top-level -> head -> dataset defaults) is handled
    centrally in `Detector.__init__`, so we do NOT resolve it here.
    - If YAML provides top-level `num_classes`, it is preserved. Otherwise it is
    left unset (None) and inferred later.
    """
    yaml_text, src = Detector._read_yaml_source_text(source)
    if _source_override is not None:
        src = str(_source_override)

    data = load_yaml(yaml_text)
    apply_overrides(data, overrides)

    neck_name, neck_params = split_block(data.get("neck", {}))
    neck_entry = get_neck_entry(neck_name)
    neck_cfg_cls = Detector._cfg_class_from_entry(
        neck_entry, kind="Neck", name=neck_name
    )
    neck_params = Detector._inject_name_if_possible(
        neck_cfg_cls, neck_params, neck_name
    )
    neck_cfg: Any = strict_dataclass_from_dict(
        neck_cfg_cls,
        neck_params,
        where=f"Detector.from_yaml.neck[{neck_name}]",
    )

    head_name, head_params = split_block(data.get("head", {}))
    head_entry = get_head_entry(head_name)
    head_cfg_cls = Detector._cfg_class_from_entry(
        head_entry, kind="Head", name=head_name
    )
    head_params = Detector._inject_name_if_possible(
        head_cfg_cls, head_params, head_name
    )
    head_cfg: Any = strict_dataclass_from_dict(
        head_cfg_cls,
        head_params,
        where=f"Detector.from_yaml.head[{head_name}]",
    )

    cfg = DetectorCfg._from_dict(
        {
            "num_classes": data.get("num_classes", None),
            "conf_threshold": data.get(
                "conf_threshold", DetectorCfg().conf_threshold
            ),
            "nms_threshold": data.get("nms_threshold", DetectorCfg().nms_threshold),
            "pretrained_source": data.get(
                "pretrained_source", DetectorCfg().pretrained_source
            ),
            "backbone": data.get("backbone", {}),
            "neck": neck_cfg,
            "head": head_cfg,
            "loss": data.get("loss", None),
        }
    )

    return Detector(
        cfg=cfg,
        cfg_yaml_text=yaml_text,
        cfg_yaml_source=src,
        cfg_zoo_key=_zoo_key,
    )

list_bbox_configs() staticmethod

Return available bbox (detection) config zoo keys.

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
442
443
444
445
@staticmethod
def list_bbox_configs() -> list[str]:
    """Return available bbox (detection) config zoo keys."""
    return sorted(_DETECTOR_BBOX_CONFIGS.keys())

list_instance_mask_configs() staticmethod

Return available instance-mask (segmentation) config zoo keys.

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
447
448
449
450
@staticmethod
def list_instance_mask_configs() -> list[str]:
    """Return available instance-mask (segmentation) config zoo keys."""
    return sorted(_DETECTOR_INSTANCE_MASK_CONFIGS.keys())

config_descriptions_bbox() staticmethod

Optional short descriptions for bbox configs.

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
452
453
454
455
@staticmethod
def config_descriptions_bbox() -> dict[str, str]:
    """Optional short descriptions for bbox configs."""
    return dict(_DETECTOR_CONFIG_DESCRIPTIONS_BBOX)

config_descriptions_instance_mask() staticmethod

Optional short descriptions for instance-mask configs.

Source code in src/deepvisiontools/models/detectors/models/facades/detectors.py
457
458
459
460
@staticmethod
def config_descriptions_instance_mask() -> dict[str, str]:
    """Optional short descriptions for instance-mask configs."""
    return dict(_DETECTOR_CONFIG_DESCRIPTIONS_INSTANCE_MASK)

TABDet(cfg, *, cfg_yaml_text=None, cfg_yaml_source=None, cfg_zoo_key=None)

Bases: torch.nn.Module

Facade torch.nn.Module for TABDet models. TABDet include several heads / necks. The main difference with Detectors is that they run backbone on small patches before merging. TABDet must preferably be built from yaml Note that detector are input size flexible, even when using timm transformer encoders.

Parameters:

Name Type Description Default
cfg deepvisiontools.models.detectors.models.config.config.TABDetCfg

dataclass that configures the detector.

required
cfg_yaml_text str | None, **optional**

Defaults to None.

None
cfg_yaml_source str | None, **optional**

Defaults to None.

None
cfg_zoo_key str | None, **optional**

Defaults to None.

None
Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def __init__(
    self,
    cfg: TABDetCfg,
    *,
    cfg_yaml_text: str | None = None,
    cfg_yaml_source: str | None = None,
    cfg_zoo_key: str | None = None,
) -> None:
    super().__init__()

    from .....config import current  # local import avoids circulars

    def _is_instance_mask_head(name: str) -> bool:
        n = (name or "").lower()
        return ("mask" in n) or (n == "cascademaskrcnnhead")

    head_name = str(getattr(getattr(cfg, "head", None), "name", "") or "")

    if cfg.num_classes is not None:
        resolved_nc = int(cfg.num_classes)
    else:
        head_cfg_nc = getattr(cfg.head, "num_classes", None)
        if head_cfg_nc is not None:
            resolved_nc = int(head_cfg_nc)
        else:
            resolved_nc = int(
                current().data_instance_mask.num_classes
                if _is_instance_mask_head(head_name)
                else current().data_box.num_classes
            )

    cfg = replace(cfg, num_classes=resolved_nc)

    self.cfg = cfg
    self.cfg_yaml_text = cfg_yaml_text
    self.cfg_yaml_source = cfg_yaml_source
    self.cfg_zoo_key = cfg_zoo_key

    self.model, self.patcher = self._build_torch_model_and_patcher(cfg)

    # New: optional whole-model COCO pretrained load
    self._maybe_load_full_coco_pretrained()

    head_cfg = getattr(cfg, "head", None)
    head_name = str(getattr(head_cfg, "name", "") or "")
    append_gt = bool(getattr(head_cfg, "proposal_append_gt", False))
    self.requires_targets_in_train = (head_name == "CascadeRCNNHead") and append_gt

    resolved_loss = resolve_default_loss(
        head_name=str(getattr(cfg.head, "name", "")),
        explicit_loss=getattr(cfg.loss, "name", None),
    )
    self.loss = build_loss(
        self.model.head,
        cast(
            Literal["ATSS_VFNet", "CascadeRCNN", "CascadeMaskRCNN"],
            resolved_loss,
        ),
    )

    if self.cfg_yaml_text is None and hasattr(cfg, "export_to_yaml_text"):
        self.cfg_yaml_text = cfg.export_to_yaml_text()
        self.cfg_yaml_source = self.cfg_yaml_source or "cfg.export_to_yaml_text"

from_yaml(source, overrides=None, _source_override=None, _zoo_key=None) staticmethod

Build from YAML file path or YAML text. Supports overrides.

Notes: - This method only parses YAML into cfg objects. - num_classes inference (top-level -> head -> dataset defaults) is handled centrally in TABDet.__init__, so we do NOT resolve it here. - If YAML provides top-level num_classes, it is preserved. Otherwise it is left unset (None) and inferred later.

Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
@staticmethod
def from_yaml(
    source: str | Path,
    overrides: Mapping[str, Any] | None = None,
    _source_override: str | None = None,
    _zoo_key: str | None = None,
) -> TABDet:
    """
    Build from YAML file path or YAML text. Supports overrides.

    Notes:
    - This method only parses YAML into cfg objects.
    - `num_classes` inference (top-level -> head -> dataset defaults) is handled
    centrally in `TABDet.__init__`, so we do NOT resolve it here.
    - If YAML provides top-level `num_classes`, it is preserved. Otherwise it is
    left unset (None) and inferred later.
    """
    yaml_text, src = TABDet._read_yaml_source_text(source)
    if _source_override is not None:
        src = str(_source_override)

    data = load_yaml(yaml_text)
    apply_overrides(data, overrides)

    neck_name, neck_params = split_block(data.get("neck", {}))
    neck_entry = get_neck_entry(neck_name)
    neck_cfg_cls = TABDet._cfg_class_from_entry(
        neck_entry, kind="Neck", name=neck_name
    )
    neck_params = TABDet._inject_name_if_possible(
        neck_cfg_cls, neck_params, neck_name
    )
    neck_cfg: Any = strict_dataclass_from_dict(
        neck_cfg_cls,
        neck_params,
        where=f"TABDet.from_yaml.neck[{neck_name}]",
    )

    head_name, head_params = split_block(data.get("head", {}))
    head_entry = get_head_entry(head_name)
    head_cfg_cls = TABDet._cfg_class_from_entry(
        head_entry, kind="Head", name=head_name
    )
    head_params = TABDet._inject_name_if_possible(
        head_cfg_cls, head_params, head_name
    )
    head_cfg: Any = strict_dataclass_from_dict(
        head_cfg_cls,
        head_params,
        where=f"TABDet.from_yaml.head[{head_name}]",
    )

    cfg = TABDetCfg._from_dict(
        {
            "num_classes": data.get("num_classes", None),
            "conf_threshold": data.get(
                "conf_threshold", TABDetCfg().conf_threshold
            ),
            "nms_threshold": data.get("nms_threshold", TABDetCfg().nms_threshold),
            "pretrained_source": data.get(
                "pretrained_source", TABDetCfg().pretrained_source
            ),
            "backbone": data.get("backbone", {}),
            "neck": neck_cfg,
            "head": head_cfg,
            "loss": data.get("loss", None),
            "tiling": data.get("tiling", {}),
            "prefusion_score": data.get("prefusion_score", {}),
        }
    )

    return TABDet(
        cfg=cfg,
        cfg_yaml_text=yaml_text,
        cfg_yaml_source=src,
        cfg_zoo_key=_zoo_key,
    )

list_bbox_configs() staticmethod

Return available bbox (detection) config zoo keys.

Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
485
486
487
488
@staticmethod
def list_bbox_configs() -> list[str]:
    """Return available bbox (detection) config zoo keys."""
    return sorted(_TABDET_BBOX_CONFIGS.keys())

list_instance_mask_configs() staticmethod

Return available instance-mask (segmentation) config zoo keys.

Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
490
491
492
493
@staticmethod
def list_instance_mask_configs() -> list[str]:
    """Return available instance-mask (segmentation) config zoo keys."""
    return sorted(_TABDET_INSTANCE_MASK_CONFIGS.keys())

config_descriptions_bbox() staticmethod

Optional short descriptions for bbox configs.

Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
495
496
497
498
@staticmethod
def config_descriptions_bbox() -> dict[str, str]:
    """Optional short descriptions for bbox configs."""
    return dict(_TABDET_CONFIG_DESCRIPTIONS_BBOX)

config_descriptions_instance_mask() staticmethod

Optional short descriptions for instance-mask configs.

Source code in src/deepvisiontools/models/detectors/models/facades/tabdets.py
500
501
502
503
@staticmethod
def config_descriptions_instance_mask() -> dict[str, str]:
    """Optional short descriptions for instance-mask configs."""
    return dict(_TABDET_CONFIG_DESCRIPTIONS_INSTANCE_MASK)

TABSegPredParams(conf_threshold, nms_iou, max_det, mask_threshold, apply_mask_scoring, use_soft_nms, soft_nms_method, soft_nms_sigma, soft_nms_iou_thresh, soft_nms_score_thresh) dataclass

Bases: deepvisiontools.models.base.basemodel.BasePredParams

Prediction-time parameters for TABSeg (TABDet facade with CascadeMaskRCNN head).

TABDetPredParams(conf_threshold, nms_iou, max_det) dataclass

Bases: deepvisiontools.models.base.basemodel.BasePredParams

Prediction-time parameters for TABDet decoding. Controlled from global config (same as bbox config).

build_detector(*, config='default_vfnet', overrides=None, num_classes=None, supports_amp=True, autocast_dtype=torch.float16, device=None, use_amp=None, pad_multiple=32, **extras)

Build a DeepVision detector wrapper, registered as "detector".

This builder wraps the internal Detector facade, typically configured with a VFNet-style detection head, inside the DeepVisionTools DeepVisionModel API. It supports predefined zoo configs, YAML file paths and raw YAML strings.

Parameters:

Name Type Description Default
config str

Detector configuration. Can be a registered config name, a YAML file path, or raw YAML text accepted by DetectorFacade. Defaults to "default_vfnet".

'default_vfnet'
overrides collections.abc.Mapping[str, typing.Any] | None

Configuration overrides passed to DetectorFacade.from_config. Common keys include backbone, head, optimizer-related model settings or "num_classes". Defaults to None.

None
num_classes int | None

Number of detection classes. When provided, it is injected into overrides["num_classes"]. When None, the resolved facade config must provide a valid class count, usually from the current bbox configuration. Defaults to None.

None
supports_amp bool

Whether this backend supports autocast mixed precision. Defaults to True.

True
autocast_dtype torch.dtype

Autocast dtype used by DeepVisionModel. Defaults to torch.float16.

torch.float16
device str | torch.device | None

Device used to place the model. If None, device resolution is delegated to DeepVisionModel. Defaults to None.

None
use_amp bool | None

Force-enable or force-disable AMP. If None, the global/default DeepVisionTools AMP policy is used. Defaults to None.

None
pad_multiple int

Spatial multiple used by preprocessing to pad images and targets before forwarding them to the detector. Defaults to 32.

32
extras

Additional keyword arguments kept for registry/export compatibility.

{}

Returns:

Name Type Description
DeepVisionModel deepvisiontools.models.base.basemodel.DeepVisionModel

A fully wired detection model with bbox capabilities and

deepvisiontools.models.base.basemodel.DeepVisionModel

default DetectorPredParams loaded from the current configuration.

Targets and export

During training, instance-mask targets are converted to bounding boxes when needed. Exported artifacts store the effective YAML/configuration and force "backbone.pretrained": False before reloading the saved state dict.

Usage
import torch

from deepvisiontools.models import ModelFactory

# Default VFNet-style detector
model = ModelFactory(
    name="detector",
    config="default_vfnet",
    num_classes=3,
)

# Override parts of the detector config
model = ModelFactory(
    name="detector",
    config="default_vfnet",
    num_classes=3,
    overrides={
        "backbone.name": "convnextv2_base",
        "backbone.pretrained": True,
    },
)

# Control device, AMP and preprocessing padding
model = ModelFactory(
    name="detector",
    config="default_vfnet",
    num_classes=3,
    device="cuda",
    use_amp=True,
    pad_multiple=32,
)

# Inference returns BatchData containing BboxData items.
images = torch.randn(2, 3, 512, 512)
preds = model.predict(images)
preds.data_type == "bbox"
>>> True
Source code in src/deepvisiontools/models/detectors/detector.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
@MODEL_REGISTRY.register("detector")
def build_detector(
    *,
    config: str = "default_vfnet",
    overrides: Mapping[str, Any] | None = None,
    num_classes: int | None = None,
    supports_amp: bool = True,
    autocast_dtype: torch.dtype = torch.float16,
    device: str | torch.device | None = None,
    use_amp: bool | None = None,
    pad_multiple: int = 32,
    **extras,
) -> DeepVisionModel:
    """
    Build a DeepVision detector wrapper, registered as `"detector"`.

    This builder wraps the internal `Detector` facade, typically configured with a
    VFNet-style detection head, inside the DeepVisionTools `DeepVisionModel` API.
    It supports predefined zoo configs, YAML file paths and raw YAML strings.

    Args:
        config (str, optional): Detector configuration. Can be a registered config
            name, a YAML file path, or raw YAML text accepted by `DetectorFacade`.
            Defaults to `"default_vfnet"`.
        overrides (Mapping[str, Any] | None, optional): Configuration overrides passed
            to `DetectorFacade.from_config`. Common keys include backbone, head,
            optimizer-related model settings or `"num_classes"`. Defaults to None.
        num_classes (int | None, optional): Number of detection classes. When provided,
            it is injected into `overrides["num_classes"]`. When None, the resolved
            facade config must provide a valid class count, usually from the current
            bbox configuration. Defaults to None.
        supports_amp (bool, optional): Whether this backend supports autocast mixed
            precision. Defaults to True.
        autocast_dtype (torch.dtype, optional): Autocast dtype used by
            `DeepVisionModel`. Defaults to `torch.float16`.
        device (str | torch.device | None, optional): Device used to place the model.
            If None, device resolution is delegated to `DeepVisionModel`. Defaults to None.
        use_amp (bool | None, optional): Force-enable or force-disable AMP. If None,
            the global/default DeepVisionTools AMP policy is used. Defaults to None.
        pad_multiple (int, optional): Spatial multiple used by preprocessing to pad
            images and targets before forwarding them to the detector. Defaults to 32.
        extras: Additional keyword arguments kept for registry/export compatibility.

    Returns:
        DeepVisionModel: A fully wired detection model with `bbox` capabilities and
        default `DetectorPredParams` loaded from the current configuration.

    ???+ note "Targets and export"
        During training, instance-mask targets are converted to bounding boxes when
        needed. Exported artifacts store the effective YAML/configuration and force
        `"backbone.pretrained": False` before reloading the saved state dict.

    ???+ example "Usage"
        ```python
        import torch

        from deepvisiontools.models import ModelFactory

        # Default VFNet-style detector
        model = ModelFactory(
            name="detector",
            config="default_vfnet",
            num_classes=3,
        )

        # Override parts of the detector config
        model = ModelFactory(
            name="detector",
            config="default_vfnet",
            num_classes=3,
            overrides={
                "backbone.name": "convnextv2_base",
                "backbone.pretrained": True,
            },
        )

        # Control device, AMP and preprocessing padding
        model = ModelFactory(
            name="detector",
            config="default_vfnet",
            num_classes=3,
            device="cuda",
            use_amp=True,
            pad_multiple=32,
        )

        # Inference returns BatchData containing BboxData items.
        images = torch.randn(2, 3, 512, 512)
        preds = model.predict(images)
        preds.data_type == "bbox"
        >>> True
        ```
    """
    merged_overrides: dict[str, Any] = dict(overrides or {})
    if num_classes is not None:
        num_classes = int(num_classes)
        if num_classes < 1:
            raise ValueError(f"num_classes must be >= 1, got {num_classes}.")
        merged_overrides["num_classes"] = num_classes

    model = DetectorFacade.from_config(config, overrides=merged_overrides)
    cfg_num_classes = model.cfg.num_classes
    if cfg_num_classes is None:
        raise ValueError("Resolved detector config has num_classes=None.")
    resolved_num_classes = int(cfg_num_classes)
    if resolved_num_classes < 1:
        raise ValueError(f"num_classes must be >= 1, got {resolved_num_classes}.")

    pred_params = DetectorPredParams.default_from_config()

    backend = DetectorBackend(model)
    pre = DetectorPre(pad_multiple=int(pad_multiple))
    post = DetectorPost()
    loss_fn = DetectorLoss(model)

    caps = Capabilities(
        task="bbox",
        supports_amp=bool(supports_amp),
        requires_divisible=int(pad_multiple),
        description="VFNet-style detector facade wrapped for DeepVisionModel.",
    )

    dv = DeepVisionModel(
        backend=backend,
        pre=pre,
        post=post,
        loss_fn=loss_fn,
        device=device,
        pred_params=pred_params,
        use_amp=use_amp,
        caps=caps,
        autocast_dtype=autocast_dtype,
    )

    # Persist YAML text for full portability.
    # IMPORTANT: save the EFFECTIVE overrides, not the raw user overrides,
    # so num_classes is reproduced exactly when the model is reloaded.
    export_overrides = dict(merged_overrides)
    export_overrides["num_classes"] = resolved_num_classes
    # Don't use pretrained for rebuilding artifacts
    export_overrides["backbone.pretrained"] = False

    yaml_text = getattr(model, "cfg_yaml_text", None)
    dv.set_export_spec(
        builder="detector",
        model_kwargs={
            "config": (
                yaml_text
                if isinstance(yaml_text, str) and yaml_text.strip()
                else config
            ),
            "num_classes": resolved_num_classes,
            "overrides": export_overrides,
            "supports_amp": supports_amp,
            "autocast_dtype": autocast_dtype,
            "pad_multiple": int(pad_multiple),
            **extras,
        },
    )
    return dv

build_detector_seg(*, config='default_cascade_maskrcnn', overrides=None, num_classes=None, supports_amp=True, autocast_dtype=torch.float16, device=None, use_amp=None, pad_multiple=32, **extras)

Build a DeepVision detector instance segmentation wrapper, registered as "detector-seg".

This builder wraps the internal Detector facade configured with an instance segmentation head, typically Cascade Mask R-CNN-style, inside the DeepVisionTools DeepVisionModel API. It supports predefined zoo configs, YAML file paths and raw YAML strings.

Parameters:

Name Type Description Default
config str

Detector segmentation configuration. Can be a registered config name, a YAML file path, or raw YAML text accepted by DetectorFacade. Defaults to "default_cascade_maskrcnn".

'default_cascade_maskrcnn'
overrides collections.abc.Mapping[str, typing.Any] | None

Configuration overrides passed to DetectorFacade.from_config. Common keys include backbone, head and "num_classes". Defaults to None.

None
num_classes int | None

Number of instance segmentation classes. When provided, it is injected into overrides["num_classes"]. When None, the resolved facade config must provide a valid class count, usually from the current instance-mask configuration. Defaults to None.

None
supports_amp bool

Whether this backend supports autocast mixed precision. Defaults to True.

True
autocast_dtype torch.dtype

Autocast dtype used by DeepVisionModel. Defaults to torch.float16.

torch.float16
device str | torch.device | None

Device used to place the model. If None, device resolution is delegated to DeepVisionModel. Defaults to None.

None
use_amp bool | None

Force-enable or force-disable AMP. If None, the global/default DeepVisionTools AMP policy is used. Defaults to None.

None
pad_multiple int

Spatial multiple used by preprocessing to pad images and instance-mask targets before forwarding them to the detector. Defaults to 32.

32
extras

Additional keyword arguments kept for registry/export compatibility.

{}

Returns:

Name Type Description
DeepVisionModel deepvisiontools.models.base.basemodel.DeepVisionModel

A fully wired instance segmentation model with

deepvisiontools.models.base.basemodel.DeepVisionModel

instance_mask capabilities and default DetectorSegPredParams loaded from

deepvisiontools.models.base.basemodel.DeepVisionModel

the current configuration.

Export behavior

Exported artifacts store the effective YAML/configuration and force "backbone.pretrained": False before reloading the saved state dict.

Usage
import torch

from deepvisiontools.models import ModelFactory

# Default Cascade Mask R-CNN-style detector
model = ModelFactory(
    name="detector-seg",
    config="default_cascade_maskrcnn",
    num_classes=3,
)

# Override selected config values
model = ModelFactory(
    name="detector-seg",
    config="default_cascade_maskrcnn",
    num_classes=3,
    overrides={
        "backbone.name": "convnextv2_base",
        "backbone.pretrained": True,
    },
)

# Control device, AMP and preprocessing padding
model = ModelFactory(
    name="detector-seg",
    config="default_cascade_maskrcnn",
    num_classes=3,
    device="cuda",
    use_amp=True,
    pad_multiple=32,
)

# Inference returns BatchData containing InstanceMaskData items.
images = torch.randn(2, 3, 512, 512)
preds = model.predict(images)
preds.data_type == "instance_mask"
>>> True
Source code in src/deepvisiontools/models/detectors/detector_seg.py
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
@MODEL_REGISTRY.register("detector-seg")
def build_detector_seg(
    *,
    config: str = "default_cascade_maskrcnn",
    overrides: Mapping[str, Any] | None = None,
    num_classes: int | None = None,
    supports_amp: bool = True,
    autocast_dtype: torch.dtype = torch.float16,
    device: str | torch.device | None = None,
    use_amp: bool | None = None,
    pad_multiple: int = 32,
    **extras,
) -> DeepVisionModel:
    """
    Build a DeepVision detector instance segmentation wrapper, registered as `"detector-seg"`.

    This builder wraps the internal `Detector` facade configured with an instance
    segmentation head, typically Cascade Mask R-CNN-style, inside the
    DeepVisionTools `DeepVisionModel` API. It supports predefined zoo configs, YAML
    file paths and raw YAML strings.

    Args:
        config (str, optional): Detector segmentation configuration. Can be a
            registered config name, a YAML file path, or raw YAML text accepted by
            `DetectorFacade`. Defaults to `"default_cascade_maskrcnn"`.
        overrides (Mapping[str, Any] | None, optional): Configuration overrides passed
            to `DetectorFacade.from_config`. Common keys include backbone, head and
            `"num_classes"`. Defaults to None.
        num_classes (int | None, optional): Number of instance segmentation classes.
            When provided, it is injected into `overrides["num_classes"]`. When None,
            the resolved facade config must provide a valid class count, usually from
            the current instance-mask configuration. Defaults to None.
        supports_amp (bool, optional): Whether this backend supports autocast mixed
            precision. Defaults to True.
        autocast_dtype (torch.dtype, optional): Autocast dtype used by
            `DeepVisionModel`. Defaults to `torch.float16`.
        device (str | torch.device | None, optional): Device used to place the model.
            If None, device resolution is delegated to `DeepVisionModel`. Defaults to None.
        use_amp (bool | None, optional): Force-enable or force-disable AMP. If None,
            the global/default DeepVisionTools AMP policy is used. Defaults to None.
        pad_multiple (int, optional): Spatial multiple used by preprocessing to pad
            images and instance-mask targets before forwarding them to the detector.
            Defaults to 32.
        extras: Additional keyword arguments kept for registry/export compatibility.

    Returns:
        DeepVisionModel: A fully wired instance segmentation model with
        `instance_mask` capabilities and default `DetectorSegPredParams` loaded from
        the current configuration.

    ???+ note "Export behavior"
        Exported artifacts store the effective YAML/configuration and force
        `"backbone.pretrained": False` before reloading the saved state dict.

    ???+ example "Usage"
        ```python
        import torch

        from deepvisiontools.models import ModelFactory

        # Default Cascade Mask R-CNN-style detector
        model = ModelFactory(
            name="detector-seg",
            config="default_cascade_maskrcnn",
            num_classes=3,
        )

        # Override selected config values
        model = ModelFactory(
            name="detector-seg",
            config="default_cascade_maskrcnn",
            num_classes=3,
            overrides={
                "backbone.name": "convnextv2_base",
                "backbone.pretrained": True,
            },
        )

        # Control device, AMP and preprocessing padding
        model = ModelFactory(
            name="detector-seg",
            config="default_cascade_maskrcnn",
            num_classes=3,
            device="cuda",
            use_amp=True,
            pad_multiple=32,
        )

        # Inference returns BatchData containing InstanceMaskData items.
        images = torch.randn(2, 3, 512, 512)
        preds = model.predict(images)
        preds.data_type == "instance_mask"
        >>> True
        ```
    """
    merged_overrides: dict[str, Any] = dict(overrides or {})
    if num_classes is not None:
        num_classes = int(num_classes)
        if num_classes < 1:
            raise ValueError(f"num_classes must be >= 1, got {num_classes}.")
        merged_overrides["num_classes"] = num_classes

    model = DetectorFacade.from_config(config, overrides=merged_overrides)
    cfg_num_classes = model.cfg.num_classes
    if cfg_num_classes is None:
        raise ValueError("Resolved detector config has num_classes=None.")
    resolved_num_classes = int(cfg_num_classes)
    if resolved_num_classes < 1:
        raise ValueError(f"num_classes must be >= 1, got {resolved_num_classes}.")

    pred_params = DetectorSegPredParams.default_from_config()

    backend = DetectorSegBackend(model)
    pre = DetectorSegPre(pad_multiple=int(pad_multiple))
    post = DetectorSegPost()
    loss_fn = DetectorSegLoss(model)

    caps = Capabilities(
        task="instance_mask",
        supports_amp=bool(supports_amp),
        requires_divisible=int(pad_multiple),
        description="CascadeMaskRCNN-style detector facade wrapped for DeepVisionModel.",
    )

    dv = DeepVisionModel(
        backend=backend,
        pre=pre,
        post=post,
        loss_fn=loss_fn,
        device=device,
        pred_params=pred_params,
        use_amp=use_amp,
        caps=caps,
        autocast_dtype=autocast_dtype,
    )

    # Persist YAML text for portability.
    # IMPORTANT: save the EFFECTIVE overrides, not the raw user overrides,
    # so num_classes is reproduced exactly when the model is reloaded.
    export_overrides = dict(merged_overrides)
    export_overrides["num_classes"] = resolved_num_classes
    # Don't use pretrained for rebuilding artifacts
    export_overrides["backbone.pretrained"] = False

    yaml_text = getattr(model, "cfg_yaml_text", None)
    dv.set_export_spec(
        builder="detector-seg",
        model_kwargs={
            "config": (
                yaml_text
                if isinstance(yaml_text, str) and yaml_text.strip()
                else config
            ),
            "num_classes": resolved_num_classes,
            "overrides": export_overrides,
            "supports_amp": supports_amp,
            "autocast_dtype": autocast_dtype,
            "pad_multiple": int(pad_multiple),
            **extras,
        },
    )
    return dv

build_tabdet_seg(*, config='tabdet_vit-base-patch16-dinov3_cascade_maskrcnn', overrides=None, num_classes=None, supports_amp=True, autocast_dtype=torch.float16, device=None, use_amp=None, **extras)

Build a DeepVision TABDet instance segmentation wrapper, registered as "tabdet-seg".

This builder wraps the TABDet facade configured with an instance segmentation head, typically Cascade Mask R-CNN-style, inside the DeepVisionTools DeepVisionModel API. It supports predefined zoo configs, YAML file paths and raw YAML strings.

Parameters:

Name Type Description Default
config str

TABDet instance segmentation configuration. Can be a registered config name, a YAML file path, or raw YAML text accepted by TABDetFacade. Defaults to "tabdet_vit-base-patch16-dinov3_cascade_maskrcnn".

'tabdet_vit-base-patch16-dinov3_cascade_maskrcnn'
overrides collections.abc.Mapping[str, typing.Any] | None

Configuration overrides passed to TABDetFacade.from_config. Common keys include backbone, patcher, head and "num_classes". Defaults to None.

None
num_classes int | None

Number of instance segmentation classes. When provided, it is injected into overrides["num_classes"]. When None, the resolved facade config must provide a valid class count, usually from the current instance-mask configuration. Defaults to None.

None
supports_amp bool

Whether this backend supports autocast mixed precision. Defaults to True.

True
autocast_dtype torch.dtype

Autocast dtype used by DeepVisionModel. Defaults to torch.float16.

torch.float16
device str | torch.device | None

Device used to place the model. If None, device resolution is delegated to DeepVisionModel. Defaults to None.

None
use_amp bool | None

Force-enable or force-disable AMP. If None, the global/default DeepVisionTools AMP policy is used. Defaults to None.

None
extras

Additional keyword arguments kept for registry/export compatibility.

{}

Returns:

Name Type Description
DeepVisionModel deepvisiontools.models.base.basemodel.DeepVisionModel

A fully wired instance segmentation model with

deepvisiontools.models.base.basemodel.DeepVisionModel

instance_mask capabilities and default TABSegPredParams loaded from the

deepvisiontools.models.base.basemodel.DeepVisionModel

current configuration.

TABDet preprocessing

TABDet-seg preprocessing uses the facade patcher padding requirements instead of a fixed pad_multiple. This keeps image and target padding aligned with TABDet tiling and feature aggregation.

Export behavior

Exported artifacts store the effective YAML/configuration and force "backbone.pretrained": False before reloading the saved state dict.

Usage
import torch

from deepvisiontools.models import ModelFactory

# Default TABDet instance segmentation model
model = ModelFactory(
    name="tabdet-seg",
    config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
    num_classes=3,
)

# Override selected TABDet config values
model = ModelFactory(
    name="tabdet-seg",
    config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
    num_classes=3,
    overrides={
        "backbone.pretrained": True,
    },
)

# Device and AMP control
model = ModelFactory(
    name="tabdet-seg",
    config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
    num_classes=3,
    device="cuda",
    use_amp=True,
)

# Inference returns BatchData containing InstanceMaskData items.
images = torch.randn(2, 3, 512, 512)
preds = model.predict(images)
preds.data_type == "instance_mask"
>>> True
Source code in src/deepvisiontools/models/detectors/tab_seg.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
@MODEL_REGISTRY.register("tabdet-seg")
def build_tabdet_seg(
    *,
    config: str = "tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
    overrides: Mapping[str, Any] | None = None,
    num_classes: int | None = None,
    supports_amp: bool = True,
    autocast_dtype: torch.dtype = torch.float16,
    device: str | torch.device | None = None,
    use_amp: bool | None = None,
    **extras,
) -> DeepVisionModel:
    """
    Build a DeepVision TABDet instance segmentation wrapper, registered as `"tabdet-seg"`.

    This builder wraps the TABDet facade configured with an instance segmentation
    head, typically Cascade Mask R-CNN-style, inside the DeepVisionTools
    `DeepVisionModel` API. It supports predefined zoo configs, YAML file paths and
    raw YAML strings.

    Args:
        config (str, optional): TABDet instance segmentation configuration. Can be a
            registered config name, a YAML file path, or raw YAML text accepted by
            `TABDetFacade`. Defaults to
            `"tabdet_vit-base-patch16-dinov3_cascade_maskrcnn"`.
        overrides (Mapping[str, Any] | None, optional): Configuration overrides passed
            to `TABDetFacade.from_config`. Common keys include backbone, patcher, head
            and `"num_classes"`. Defaults to None.
        num_classes (int | None, optional): Number of instance segmentation classes.
            When provided, it is injected into `overrides["num_classes"]`. When None,
            the resolved facade config must provide a valid class count, usually from
            the current instance-mask configuration. Defaults to None.
        supports_amp (bool, optional): Whether this backend supports autocast mixed
            precision. Defaults to True.
        autocast_dtype (torch.dtype, optional): Autocast dtype used by
            `DeepVisionModel`. Defaults to `torch.float16`.
        device (str | torch.device | None, optional): Device used to place the model.
            If None, device resolution is delegated to `DeepVisionModel`. Defaults to None.
        use_amp (bool | None, optional): Force-enable or force-disable AMP. If None,
            the global/default DeepVisionTools AMP policy is used. Defaults to None.
        extras: Additional keyword arguments kept for registry/export compatibility.

    Returns:
        DeepVisionModel: A fully wired instance segmentation model with
        `instance_mask` capabilities and default `TABSegPredParams` loaded from the
        current configuration.

    ???+ note "TABDet preprocessing"
        TABDet-seg preprocessing uses the facade patcher padding requirements instead
        of a fixed `pad_multiple`. This keeps image and target padding aligned with
        TABDet tiling and feature aggregation.

    ???+ note "Export behavior"
        Exported artifacts store the effective YAML/configuration and force
        `"backbone.pretrained": False` before reloading the saved state dict.

    ???+ example "Usage"
        ```python
        import torch

        from deepvisiontools.models import ModelFactory

        # Default TABDet instance segmentation model
        model = ModelFactory(
            name="tabdet-seg",
            config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
            num_classes=3,
        )

        # Override selected TABDet config values
        model = ModelFactory(
            name="tabdet-seg",
            config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
            num_classes=3,
            overrides={
                "backbone.pretrained": True,
            },
        )

        # Device and AMP control
        model = ModelFactory(
            name="tabdet-seg",
            config="tabdet_vit-base-patch16-dinov3_cascade_maskrcnn",
            num_classes=3,
            device="cuda",
            use_amp=True,
        )

        # Inference returns BatchData containing InstanceMaskData items.
        images = torch.randn(2, 3, 512, 512)
        preds = model.predict(images)
        preds.data_type == "instance_mask"
        >>> True
        ```
    """
    merged_overrides: dict[str, Any] = dict(overrides or {})
    if num_classes is not None:
        num_classes = int(num_classes)
        if num_classes < 1:
            raise ValueError(f"num_classes must be >= 1, got {num_classes}.")
        merged_overrides["num_classes"] = num_classes

    model = TABDetFacade.from_config(config, overrides=merged_overrides)
    cfg_num_classes = model.cfg.num_classes
    if cfg_num_classes is None:
        raise ValueError("Resolved detector config has num_classes=None.")
    resolved_num_classes = int(cfg_num_classes)
    if resolved_num_classes < 1:
        raise ValueError(f"num_classes must be >= 1, got {resolved_num_classes}.")

    pred_params = TABSegPredParams.default_from_config()

    backend = TABSegBackend(model)
    pre = TABSegPre(model)
    post = TABSegPost()
    loss_fn = TABSegLoss(model)

    # TABDet divisibility is determined by tiler/patcher; reuse model.patcher requirements
    # As a safe default for caps we set requires_divisible=1 (tiler handles internal pad).
    caps = Capabilities(
        task="instance_mask",
        supports_amp=bool(supports_amp),
        requires_divisible=1,
        description="TABDet (tiling) + CascadeMaskRCNN head wrapped for DeepVisionModel.",
    )

    dv = DeepVisionModel(
        backend=backend,
        pre=pre,
        post=post,
        loss_fn=loss_fn,
        device=device,
        pred_params=pred_params,
        use_amp=use_amp,
        caps=caps,
        autocast_dtype=autocast_dtype,
    )

    export_overrides = dict(merged_overrides)
    export_overrides["num_classes"] = resolved_num_classes
    # Don't use pretrained for rebuilding artifacts
    export_overrides["backbone.pretrained"] = False

    yaml_text = getattr(model, "cfg_yaml_text", None)
    dv.set_export_spec(
        builder="tabdet-seg",
        model_kwargs={
            "config": (
                yaml_text
                if isinstance(yaml_text, str) and yaml_text.strip()
                else config
            ),
            "num_classes": resolved_num_classes,
            "overrides": export_overrides,
            "supports_amp": supports_amp,
            "autocast_dtype": autocast_dtype,
            **extras,
        },
    )
    return dv

build_tabdet(*, config='default_vfnet', overrides=None, num_classes=None, supports_amp=True, autocast_dtype=torch.float16, device=None, use_amp=None, **extras)

Build a DeepVision TABDet detection wrapper, registered as "tabdet".

This builder wraps the TABDet facade, a tiled-aggregated-backbone detector, inside the DeepVisionTools DeepVisionModel API. It supports predefined zoo configs, YAML file paths and raw YAML strings.

Parameters:

Name Type Description Default
config str

TABDet detection configuration. Can be a registered config name, a YAML file path, or raw YAML text accepted by TABDetFacade. Defaults to "default_vfnet".

'default_vfnet'
overrides collections.abc.Mapping[str, typing.Any] | None

Configuration overrides passed to TABDetFacade.from_config. Common keys include backbone, patcher, head and "num_classes". Defaults to None.

None
num_classes int | None

Number of detection classes. When provided, it is injected into overrides["num_classes"]. When None, the resolved facade config must provide a valid class count, usually from the current bbox configuration. Defaults to None.

None
supports_amp bool

Whether this backend supports autocast mixed precision. Defaults to True.

True
autocast_dtype torch.dtype

Autocast dtype used by DeepVisionModel. Defaults to torch.float16.

torch.float16
device str | torch.device | None

Device used to place the model. If None, device resolution is delegated to DeepVisionModel. Defaults to None.

None
use_amp bool | None

Force-enable or force-disable AMP. If None, the global/default DeepVisionTools AMP policy is used. Defaults to None.

None
extras

Additional keyword arguments kept for registry/export compatibility.

{}

Returns:

Name Type Description
DeepVisionModel deepvisiontools.models.base.basemodel.DeepVisionModel

A fully wired detection model with bbox capabilities and

deepvisiontools.models.base.basemodel.DeepVisionModel

default TABDetPredParams loaded from the current configuration.

TABDet preprocessing

TABDet preprocessing uses the facade patcher padding requirements instead of a fixed pad_multiple. This keeps image padding aligned with TABDet tiling and feature aggregation.

Export behavior

Exported artifacts store the effective YAML/configuration and force "backbone.pretrained": False before reloading the saved state dict.

Usage
import torch

from deepvisiontools.models import ModelFactory

# Default TABDet detector
model = ModelFactory(
    name="tabdet",
    config="default_vfnet",
    num_classes=3,
)

# Use a registered TABDet config and override selected values
model = ModelFactory(
    name="tabdet",
    config="tabdet_vit-base-patch16-dinov3_vfnet",
    num_classes=3,
    overrides={
        "backbone.pretrained": True,
    },
)

# Device and AMP control
model = ModelFactory(
    name="tabdet",
    config="default_vfnet",
    num_classes=3,
    device="cuda",
    use_amp=True,
)

# Inference returns BatchData containing BboxData items.
images = torch.randn(2, 3, 512, 512)
preds = model.predict(images)
preds.data_type == "bbox"
>>> True
Source code in src/deepvisiontools/models/detectors/tabdet.py
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
@MODEL_REGISTRY.register("tabdet")
def build_tabdet(
    *,
    config: str = "default_vfnet",
    overrides: Mapping[str, Any] | None = None,
    num_classes: int | None = None,
    supports_amp: bool = True,
    autocast_dtype: torch.dtype = torch.float16,
    device: str | torch.device | None = None,
    use_amp: bool | None = None,
    **extras,
) -> DeepVisionModel:
    """
    Build a DeepVision TABDet detection wrapper, registered as `"tabdet"`.

    This builder wraps the TABDet facade, a tiled-aggregated-backbone detector,
    inside the DeepVisionTools `DeepVisionModel` API. It supports predefined zoo
    configs, YAML file paths and raw YAML strings.

    Args:
        config (str, optional): TABDet detection configuration. Can be a registered
            config name, a YAML file path, or raw YAML text accepted by `TABDetFacade`.
            Defaults to `"default_vfnet"`.
        overrides (Mapping[str, Any] | None, optional): Configuration overrides passed
            to `TABDetFacade.from_config`. Common keys include backbone, patcher,
            head and `"num_classes"`. Defaults to None.
        num_classes (int | None, optional): Number of detection classes. When provided,
            it is injected into `overrides["num_classes"]`. When None, the resolved
            facade config must provide a valid class count, usually from the current
            bbox configuration. Defaults to None.
        supports_amp (bool, optional): Whether this backend supports autocast mixed
            precision. Defaults to True.
        autocast_dtype (torch.dtype, optional): Autocast dtype used by
            `DeepVisionModel`. Defaults to `torch.float16`.
        device (str | torch.device | None, optional): Device used to place the model.
            If None, device resolution is delegated to `DeepVisionModel`. Defaults to None.
        use_amp (bool | None, optional): Force-enable or force-disable AMP. If None,
            the global/default DeepVisionTools AMP policy is used. Defaults to None.
        extras: Additional keyword arguments kept for registry/export compatibility.

    Returns:
        DeepVisionModel: A fully wired detection model with `bbox` capabilities and
        default `TABDetPredParams` loaded from the current configuration.

    ???+ note "TABDet preprocessing"
        TABDet preprocessing uses the facade patcher padding requirements instead of
        a fixed `pad_multiple`. This keeps image padding aligned with TABDet tiling
        and feature aggregation.

    ???+ note "Export behavior"
        Exported artifacts store the effective YAML/configuration and force
        `"backbone.pretrained": False` before reloading the saved state dict.

    ???+ example "Usage"
        ```python
        import torch

        from deepvisiontools.models import ModelFactory

        # Default TABDet detector
        model = ModelFactory(
            name="tabdet",
            config="default_vfnet",
            num_classes=3,
        )

        # Use a registered TABDet config and override selected values
        model = ModelFactory(
            name="tabdet",
            config="tabdet_vit-base-patch16-dinov3_vfnet",
            num_classes=3,
            overrides={
                "backbone.pretrained": True,
            },
        )

        # Device and AMP control
        model = ModelFactory(
            name="tabdet",
            config="default_vfnet",
            num_classes=3,
            device="cuda",
            use_amp=True,
        )

        # Inference returns BatchData containing BboxData items.
        images = torch.randn(2, 3, 512, 512)
        preds = model.predict(images)
        preds.data_type == "bbox"
        >>> True
        ```
    """
    merged_overrides: dict[str, Any] = dict(overrides or {})
    if num_classes is not None:
        num_classes = int(num_classes)
        if num_classes < 1:
            raise ValueError(f"num_classes must be >= 1, got {num_classes}.")
        merged_overrides["num_classes"] = num_classes

    model = TABDetFacade.from_config(config, overrides=merged_overrides)
    cfg_num_classes = model.cfg.num_classes
    if cfg_num_classes is None:
        raise ValueError("Resolved detector config has num_classes=None.")
    resolved_num_classes = int(cfg_num_classes)
    if resolved_num_classes < 1:
        raise ValueError(f"num_classes must be >= 1, got {resolved_num_classes}.")

    pred_params = TABDetPredParams.default_from_config()

    backend = TABDetBackend(model)
    pre = TABDetPre(model)
    post = TABDetPost()
    loss_fn = TABDetLoss(model)

    caps = Capabilities(
        task="bbox",
        supports_amp=bool(supports_amp),
        requires_divisible=None,
        description="TABDet (tiled-aggregated-backbone) detector wrapped for DeepVisionModel.",
    )

    dv = DeepVisionModel(
        backend=backend,
        pre=pre,
        post=post,
        loss_fn=loss_fn,
        device=device,
        pred_params=pred_params,
        use_amp=use_amp,
        caps=caps,
        autocast_dtype=autocast_dtype,
    )

    export_overrides = dict(merged_overrides)
    export_overrides["num_classes"] = resolved_num_classes
    # Don't use pretrained for rebuilding artifacts
    export_overrides["backbone.pretrained"] = False

    yaml_text = getattr(model, "cfg_yaml_text", None)
    dv.set_export_spec(
        builder="tabdet",
        model_kwargs={
            "config": (
                yaml_text
                if isinstance(yaml_text, str) and yaml_text.strip()
                else config
            ),
            "num_classes": resolved_num_classes,
            "overrides": export_overrides,
            "supports_amp": supports_amp,
            "autocast_dtype": autocast_dtype,
            **extras,
        },
    )
    return dv