BNNR

Object Detection

BNNR supports object detection as a first-class task since v0.2.0. Current PyPI release: v0.2.6 (recommended for Ultralytics YOLO + detection XAI fixes). The same Train → Explain → Improve → Prove loop applies: train a detector, generate XAI saliency for bounding boxes, improve with detection-aware augmentations and ICD/AICD, and prove with mAP metrics and structured reports.


Supported Models

Torchvision Detectors

Any torchvision-style model whose forward returns losses in train mode and prediction dicts in eval mode:

  • Faster R-CNN (fasterrcnn_resnet50_fpn)
  • RetinaNet (retinanet_resnet50_fpn)
  • SSD (ssd300_vgg16)
  • FCOS (fcos_resnet50_fpn)

Wrap with DetectionAdapter:

from torchvision.models.detection import retinanet_resnet50_fpn
from bnnr import DetectionAdapter
 
model = retinanet_resnet50_fpn(weights="DEFAULT")
 
adapter = DetectionAdapter(
    model=model,
    optimizer=torch.optim.AdamW(model.parameters(), lr=1e-4),
    device="auto",
    score_threshold=0.05,
)

Constructor parameters:

ParameterDefaultDescription
modelrequiredTorchvision detection model
optimizerrequiredPyTorch optimizer
target_layersNoneLayers for XAI saliency (e.g. [model.backbone.body.layer4])
device"cuda"Device string or "auto"
schedulerNoneOptional LR scheduler
use_ampFalseEnable automatic mixed precision
score_threshold0.05Min confidence for predictions

Ultralytics YOLO

For YOLOv8 and compatible Ultralytics models, use UltralyticsDetectionAdapter:

from bnnr.detection_adapter import UltralyticsDetectionAdapter
 
adapter = UltralyticsDetectionAdapter(
    model_name="yolov8n.pt",
    device="auto",
    num_classes=80,
    lr=1e-3,
)
ParameterDefaultDescription
model_name"yolov8n.pt"Ultralytics model path or name
device"cuda"Device string
score_threshold0.05Min confidence for predictions
num_classesNoneNumber of classes (auto-detected if None)
lr1e-3Learning rate (used when optimizer is None)
optimizerNoneCustom optimizer (built automatically if None)
use_ampFalseEnable automatic mixed precision

Both adapters implement train_step, eval_step, epoch_end_eval, epoch_end, state_dict, load_state_dict, get_target_layers, and get_model.

For raw ultralytics.nn.tasks modules without this adapter, detection XAI stays disabled; see Troubleshooting.


Dataset Format

Detection datasets must return (image, target, index) tuples where:

  • imagetorch.Tensor of shape (C, H, W), values in [0, 1]
  • targetdict with keys:
    • boxes(N, 4) float tensor in xyxy format
    • labels(N,) int64 tensor (class ids, 0 = background)
    • Optional: area, iscrowd, image_id
  • index — integer sample index

Collate Functions

Standard PyTorch collation doesn't work for variable-length targets. Use the provided collate functions:

from bnnr import detection_collate_fn_with_index
 
train_loader = DataLoader(
    dataset,
    batch_size=4,
    collate_fn=detection_collate_fn_with_index,
)
  • detection_collate_fn(batch)(Tensor[B,C,H,W], list[dict])
  • detection_collate_fn_with_index(batch)(Tensor[B,C,H,W], list[dict], Tensor[B])

Detection Augmentations

All detection augmentations are bbox-aware — they transform both the image and bounding boxes consistently. They subclass BboxAwareAugmentation.

Built-in Transforms

ClassDescriptionKey parameters
DetectionHorizontalFlipHorizontal flip with bbox mirroringprobability
DetectionVerticalFlipVertical flip with bbox mirroringprobability
DetectionRandomRotate9090° rotation with bbox transformprobability
DetectionRandomScaleRandom resize with bbox scalingprobability, scale_range=(0.8, 1.2)
MosaicAugmentation4-image mosaic compositionprobability, output_size=(640, 640)
DetectionMixUpAlpha-blend two images with merged targetsprobability, alpha_range=(0.3, 0.7)
AlbumentationsBboxAugmentationAlbumentations wrapper with bbox supporttransform, probability

Detection ICD / AICD

XAI-driven augmentations that use bounding-box saliency priors:

ClassBehavior
DetectionICDMasks high-saliency (object) tiles — forces the model to learn from context
DetectionAICDMasks low-saliency (background) tiles — sharpens focus on key features

Shared parameters:

ParameterDefaultDescription
threshold_percentile70.0Saliency threshold for tile masking
tile_size8Tile grid size in pixels
fill_strategy"gaussian_blur"Fill method: gaussian_blur, local_mean, global_mean, noise, solid
probability1.0Application probability

Presets

from bnnr.detection_augmentations import get_detection_preset
 
augmentations = get_detection_preset("standard")  # "light", "standard", "aggressive"

Configuration

Set task="detection" in BNNRConfig:

from bnnr import BNNRConfig
 
config = BNNRConfig(
    task="detection",
    m_epochs=5,
    max_iterations=3,
    detection_bbox_format="xyxy",
    detection_score_threshold=0.5,
    metrics=["map_50", "map_50_95", "loss"],
)

Detection-specific Fields

FieldDefaultDescription
task"classification"Set to "detection"
detection_bbox_format"xyxy"Box format: xyxy, xywh, or cxcywh
detection_score_threshold0.5Confidence threshold for evaluation
detection_targets_mode"auto"Augmentation target mode: auto, image_only, bbox_aware
detection_class_namesNoneOptional list of class names for reports

Auto-default behavior:

  • If still at classification defaults, selection_metric becomes map_50
  • If still at classification defaults, metrics becomes [map_50, map_50_95, loss]

See Configuration for the full field reference including advanced detection fields.

Detection Metrics

Metric keyDescription
map_50Mean Average Precision at IoU 0.50
map_50_95Mean Average Precision at IoU 0.50:0.95
lossTraining loss

Per-class AP and confusion matrices are computed automatically during evaluation.


Detection XAI

BNNR generates detection-specific XAI visualizations:

  • Backbone saliency — class-agnostic activation heatmap from the detector backbone
  • Occlusion sensitivity — per-box saliency via systematic occlusion grids
  • Triptych panels — ground-truth boxes, saliency overlay, and prediction boxes side by side

XAI is generated automatically when xai_enabled=True (default). For Ultralytics models, use UltralyticsDetectionAdapter to enable full XAI support.

XAI API

  • generate_detection_saliency(model, images, target_layers, device, forward_layout) — backbone activation–based saliency
  • compute_detection_box_saliency_occlusion(...) — per-box occlusion grid saliency
  • draw_boxes_on_image(...) — draw xyxy boxes with labels, scores, and class names
  • overlay_saliency_heatmap(...) — blend saliency with colormap
  • save_detection_xai_panels(...) — writes ground-truth, saliency, and prediction panels

Full Example

import torch
from torch.utils.data import DataLoader
from torchvision.models.detection import retinanet_resnet50_fpn
from bnnr import (
    BNNRConfig, BNNRTrainer, DetectionAdapter,
    DetectionHorizontalFlip, DetectionRandomScale,
    DetectionICD, detection_collate_fn_with_index,
)
 
model = retinanet_resnet50_fpn(weights="DEFAULT")
adapter = DetectionAdapter(
    model=model,
    optimizer=torch.optim.AdamW(model.parameters(), lr=1e-4),
    device="auto",
)
 
augmentations = [
    DetectionHorizontalFlip(probability=0.5),
    DetectionRandomScale(probability=0.5, scale_range=(0.8, 1.2)),
    DetectionICD(probability=0.3),
]
 
config = BNNRConfig(
    task="detection",
    m_epochs=5,
    max_iterations=3,
    metrics=["map_50", "map_50_95", "loss"],
)
 
trainer = BNNRTrainer(adapter, train_loader, val_loader, augmentations, config)
result = trainer.run()
print(f"Best mAP@50: {result.best_metrics}")

Examples and Notebooks

  • examples/detection/showcase_yolo_coco128.py — YOLO + COCO128 with auto-download, dashboard, and mAP tracking
  • examples/detection/showcase_voc.py — Pascal VOC 2007 with full augmentation suite and XAI saliency
  • examples/detection/bnnr_detection_demo.ipynb — interactive Jupyter notebook

See Examples Guide for run commands and smoke tests.