API Reference: Metrics & Datasets¶
Performance evaluation metrics and dataset interfaces for CoreCV.
Evaluation Metrics¶
Classification Metrics¶
corecv.metrics.classification
¶
GPU-native classification metrics engine for CoreCV.
Provides an accumulator-based :class:ClassificationMetrics that computes
accuracy, top-k accuracy, precision, recall, and F1 scores — all on VRAM
with zero CPU-GPU synchronisations during update(). Intermediate
confusion-matrix counts are maintained in GPU tensors via
nn.register_buffer so they travel with .to(device) automatically.
The compute() method performs only the final scalar divisions and returns
a plain Python dict of float values — that is the only point at
which implicit CPU transfer occurs (via tensor.item()).
No pycocotools, no Python for-loops, no .cpu() calls in hot paths.
Example
import torch from corecv.metrics.classification import ClassificationMetrics device = torch.device("cuda" if torch.cuda.is_available() else "cpu") metrics = ClassificationMetrics(num_classes=10, device=device) logits = torch.randn(32, 10, device=device) targets = torch.randint(0, 10, (32,), device=device) metrics.update(logits, targets) results = metrics.compute() results["accuracy"] # Top-1 accuracy 0.125
ClassificationMetrics(num_classes, top_k=(1, 5), device='cpu')
¶
Bases: Module
Accumulator-based single-label multi-class classification metrics.
Maintains per-class true-positive, false-positive, and false-negative
counts in VRAM-resident buffers so that update() never triggers a
CPU-GPU synchronisation. Only compute() performs the final
reductions.
Supported metrics:
- accuracy — Top-1 accuracy (mean over batch).
- top{k}_accuracy — Top-k accuracy for each k in
top_k. - precision_macro / recall_macro / f1_score_macro — Macro-averaged precision, recall, and F1 (per-class, then averaged).
- precision_micro / recall_micro / f1_score_micro — Micro-averaged (global TP, FP, FN pooled before ratio).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_classes
|
int
|
Number of mutually-exclusive classes. |
required |
top_k
|
tuple[int, ...]
|
Tuple of k values for top-k accuracy reporting.
Default |
(1, 5)
|
device
|
device | str
|
Device on which to allocate the accumulator buffers. |
'cpu'
|
Example
metrics = ClassificationMetrics(num_classes=100, top_k=(1, 5), device="cuda") for logits, targets in loader: ... metrics.update(logits, targets) print(metrics.compute())
Initialise ClassificationMetrics with num_classes, top_k, and device.
Source code in src/corecv/metrics/classification.py
compute()
¶
Compute all metrics from the accumulated state.
Returns:
| Type | Description |
|---|---|
dict[str, float | Tensor]
|
Dictionary with the following keys: |
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
Source code in src/corecv/metrics/classification.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 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 212 213 214 215 216 217 218 | |
reset()
¶
update(preds, targets)
¶
Accumulate a batch of predictions and ground-truth labels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
preds
|
Tensor
|
Model output of shape |
required |
targets
|
Tensor
|
Ground-truth class indices of shape |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If tensor shapes or value ranges are invalid. |
Source code in src/corecv/metrics/classification.py
Detection Metrics¶
corecv.metrics.detection
¶
GPU-native detection metrics engine for CoreCV.
Provides an accumulator-based :class:DetectionMetrics that computes
mAP@50 and mAP@50:95 — the COCO-style mean Average Precision metrics —
entailining zero CPU-GPU synchronisations during update().
The implementation is a fully vectorised, GPU-resident alternative to
pycocotools. Per-class TP/FP counts for every IoU threshold are
maintained in VRAM via nn.register_buffer. The compute() method
performs precision-recall curve computation and AP integration, then
returns a plain Python dict.
No pycocotools dependency, no Python for-loops over individual predictions,
no .cpu() calls in hot paths.
IoU computation uses torchvision.ops.box_iou which runs on GPU via
custom CUDA kernels.
Example
import torch from corecv.metrics.detection import DetectionMetrics device = torch.device("cuda" if torch.cuda.is_available() else "cpu") metrics = DetectionMetrics(num_classes=80, device=device)
Per-image predictions and targets¶
pred_boxes = [torch.randn(5, 4, device=device).abs() * 100 for _ in range(4)] pred_scores = [torch.rand(5, device=device) for _ in range(4)] pred_labels = [torch.randint(0, 80, (5,), device=device) for _ in range(4)] target_boxes = [torch.randn(3, 4, device=device).abs() * 100 for _ in range(4)] target_labels = [torch.randint(0, 80, (3,), device=device) for _ in range(4)] metrics.update(pred_boxes, pred_scores, pred_labels, target_boxes, target_labels) results = metrics.compute() results["map50"] 0.0
DetectionMetrics(num_classes, iou_thresholds=None, device='cpu')
¶
Bases: Module
Accumulator-based detection metrics (mAP@50, mAP@50:95).
Implements a vectorised version of the COCO mAP computation entirely
in VRAM. For each IoU threshold and each class, predictions are sorted
by confidence and matched greedily to ground-truth targets. The
resulting TP/FP indicator arrays are accumulated in buffers and
processed in compute() to build precision-recall curves and
integrate AP via the all-point interpolation method (area under the
PR curve).
Supported metrics:
- map50 — mAP at IoU threshold 0.50.
- map50_95 — mAP averaged over IoU thresholds 0.50 : 0.05 : 0.95 (10 thresholds by default).
- per_class_ap50 — AP@50 per class as a
Tensor. - per_class_ap50_95 — AP@50:95 per class as a
Tensor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_classes
|
int
|
Number of object classes (excluding background). |
required |
iou_thresholds
|
Tensor | list[float] | None
|
IoU thresholds at which to compute AP.
Default |
None
|
device
|
device | str
|
Device on which to allocate accumulator buffers. |
'cpu'
|
Note
Boxes must be in (x1, y1, x2, y2) (top-left, bottom-right)
format. No coordinate conversion is performed internally.
Example
metrics = DetectionMetrics(num_classes=80, device="cuda")
Accumulate over an epoch ...¶
results = metrics.compute()
Initialise DetectionMetrics with num_classes, iou_thresholds, and device.
Source code in src/corecv/metrics/detection.py
compute()
¶
Compute mAP metrics from the accumulated state.
Returns:
| Type | Description |
|---|---|
dict[str, float | Tensor]
|
Dictionary with the following keys: |
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
Source code in src/corecv/metrics/detection.py
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 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 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 | |
reset()
¶
Reset all accumulator state.
Source code in src/corecv/metrics/detection.py
update(pred_boxes, pred_scores, pred_labels, target_boxes, target_labels)
¶
Accumulate detection results for a batch of images.
All tensor arguments are lists-of-tensors, one element per image in the batch. Empty tensors (zero detections or zero targets) are supported.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pred_boxes
|
list[Tensor]
|
|
required |
pred_scores
|
list[Tensor]
|
|
required |
pred_labels
|
list[Tensor]
|
|
required |
target_boxes
|
list[Tensor]
|
|
required |
target_labels
|
list[Tensor]
|
|
required |
Source code in src/corecv/metrics/detection.py
Segmentation Metrics¶
corecv.metrics.segmentation
¶
GPU-native semantic segmentation metrics engine for CoreCV.
Provides an accumulator-based :class:SegmentationMetrics that computes
mean IoU, pixel accuracy, and mean Dice coefficient — all on VRAM with
zero CPU-GPU synchronisations during update(). Per-class
intersection and union counts are stored in GPU-resident buffers via
nn.register_buffer.
The compute() method performs only the final reductions and returns a
plain Python dict — that is the only point where implicit CPU transfer
occurs.
No pycocotools, no Python for-loops, no .cpu() calls in hot paths.
Example
import torch from corecv.metrics.segmentation import SegmentationMetrics device = torch.device("cuda" if torch.cuda.is_available() else "cpu") metrics = SegmentationMetrics(num_classes=21, device=device) logits = torch.randn(4, 21, 128, 128, device=device) targets = torch.randint(0, 21, (4, 128, 128), device=device) metrics.update(logits, targets) results = metrics.compute() results["miou"] 0.05
SegmentationMetrics(num_classes, ignore_index=-100, device='cpu')
¶
Bases: Module
Accumulator-based semantic segmentation metrics.
Maintains per-class intersection and union counts in VRAM-resident
buffers so that update() never triggers a CPU-GPU synchronisation.
Only compute() performs the final divisions.
Supported metrics:
- miou — Mean Intersection-over-Union averaged over valid classes.
- pixel_accuracy — Fraction of correctly classified pixels (among valid, non-ignored pixels).
- mean_dice — Mean Dice coefficient averaged over valid classes.
- per_class_iou — IoU for each class as a
Tensorof shape(num_classes,). - per_class_dice — Dice for each class as a
Tensorof shape(num_classes,).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_classes
|
int
|
Number of segmentation classes. |
required |
ignore_index
|
int
|
Class index to exclude from metric computation.
Default |
-100
|
device
|
device | str
|
Device on which to allocate accumulator buffers. |
'cpu'
|
Example
metrics = SegmentationMetrics(num_classes=21, ignore_index=255, device="cuda") for logits, targets in loader: ... metrics.update(logits, targets) print(metrics.compute()["miou"])
Initialise SegmentationMetrics with num_classes, ignore_index, and device.
Source code in src/corecv/metrics/segmentation.py
compute()
¶
Compute all metrics from the accumulated state.
Returns:
| Type | Description |
|---|---|
dict[str, float | Tensor]
|
Dictionary with the following keys: |
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
dict[str, float | Tensor]
|
|
Source code in src/corecv/metrics/segmentation.py
reset()
¶
Reset all accumulator buffers to zero.
update(preds, targets)
¶
Accumulate a batch of predictions and ground-truth masks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
preds
|
Tensor
|
Logits of shape |
required |
targets
|
Tensor
|
Ground-truth class indices of shape |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If tensor shapes or value ranges are invalid. |
Source code in src/corecv/metrics/segmentation.py
Datasets & Caching¶
Classification Datasets¶
corecv.data.datasets.classification
¶
Image classification dataset with Albumentations transform support.
Provides a standard ImageFolder-style dataset that loads images from
class-named subdirectories, applies optional Albumentations transforms
(including those from :mod:corecv.data.transforms), and returns
(image, label) tuples where image is a [C, H, W] tensor and
label is an integer class index.
The dataset is designed to integrate seamlessly with
:class:~corecv.data.transforms.CoordinatedTransform but also accepts
any callable that receives an image keyword argument and returns a
result with an image attribute (e.g. :class:~albumentations.Compose
which returns a dict with an "image" key).
Example
from corecv.data.datasets import ClassificationDataset dataset = ClassificationDataset("path/to/data") image, label = dataset[0] image.shape torch.Size([3, 224, 224]) label 0
ClassificationDataset(root, transform=None, transforms=None, image_size=None)
¶
Image classification dataset following the ImageFolder convention.
Organises images by class subdirectories under a root directory.
Supports optional Albumentations transforms (e.g.
:class:~corecv.data.transforms.CoordinatedTransform) and returns
(image, label) tuples ready for model training.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Path
|
Root directory containing class-named subdirectories. |
transform |
Callable[..., object] | None
|
Optional callable that accepts |
classes |
list[str]
|
Sorted list of class names derived from folder names. |
class_to_idx |
dict[str, int]
|
Mapping from class name to integer index. |
samples |
list[tuple[str, int]]
|
List of |
Initialise the dataset by scanning root for class folders.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
Path to dataset root containing class subdirectories. |
required |
transform
|
Callable[..., object] | bool | None
|
Transform pipeline or boolean flag. Pass |
None
|
transforms
|
Callable[..., object] | bool | None
|
Alias for transform. |
None
|
image_size
|
tuple[int, int] | None
|
Target |
None
|
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If root does not exist. |
Source code in src/corecv/data/datasets/classification.py
__getitem__(index)
¶
Return the image-label pair at the given index.
Source code in src/corecv/data/datasets/classification.py
Detection Datasets (COCO)¶
corecv.data.datasets.detection
¶
Detection dataset for object detection tasks.
Provides a :class:DetectionDataset that supports COCO JSON and YOLO
txt annotation formats with a hybrid cache strategy. On first
initialisation an O(N) pre-flight check validates all annotations and
writes a persistent cache file (.npz) containing compact NumPy
arrays for bounding boxes and labels. Subsequent runs load directly
from the cache, bypassing annotation-file I/O each epoch. Cache
validity is determined by comparing file modification timestamps.
DetectionDataset(root, annotation_path=None, format='coco', transform=None, transforms=None, image_size=(640, 640), cache_dir=None, use_cache=True, bbox_format='norm_xyxy', class_names=None)
¶
Bases: Dataset[tuple[Tensor, Tensor, Tensor]]
Dataset for object detection with COCO and YOLO annotation formats.
Implements a hybrid cache strategy:
- On first use, an O(N) pre-flight check scans every annotation
file, validates bounding boxes, and writes a persistent cache
file (
.npz) containing compact NumPy arrays for bboxes and labels. - On subsequent runs the cache is loaded directly into RAM, avoiding per-epoch I/O on annotation files.
- Cache invalidation compares stored file modification times against the current filesystem mtimes. If any source file has changed the cache is rebuilt.
Each sample is a (image, bboxes, labels) tuple where:
image—torch.Tensor, shape(C, H, W), dtypetorch.float32, values in[0, 1](if untransformed) or normalised per the transform pipeline.bboxes—torch.Tensor, shape(N, 4)in XYXY format, either absolute pixels or normalised[0, 1].labels—torch.Tensor, shape(N,)with class indices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
Root directory containing images and (for YOLO) label files. |
required |
annotation_path
|
str | Path | None
|
Path to annotation file (COCO JSON) or label
directory (YOLO). If |
None
|
format
|
str
|
Annotation format — |
'coco'
|
transform
|
CoordinatedTransform | bool | None
|
Optional :class: |
None
|
image_size
|
tuple[int, int]
|
Target |
(640, 640)
|
cache_dir
|
str | Path | None
|
Directory for the cache file. If |
None
|
use_cache
|
bool
|
Whether to enable the on-disk cache. Pass
|
True
|
bbox_format
|
Literal['xyxy', 'norm_xyxy']
|
Output bounding box format. |
'norm_xyxy'
|
class_names
|
Sequence[str] | None
|
Optional list of class names for COCO. If
|
None
|
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the root directory, annotation path, or an image referenced in the annotations does not exist. |
ValueError
|
If an unsupported format is given, or if an annotation contains invalid bounding boxes. |
Example
from corecv.data.datasets import DetectionDataset dataset = DetectionDataset( ... root="data/coco", ... format="coco", ... bbox_format="norm_xyxy", ... ) image, bboxes, labels = dataset[0] image.shape torch.Size([3, 640, 640]) bboxes.shape torch.Size([3, 4]) labels.shape torch.Size([3])
Initialise the detection dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
Root directory containing images. |
required |
annotation_path
|
str | Path | None
|
Path to annotation file or label dir. |
None
|
format
|
str
|
Annotation format ( |
'coco'
|
transform
|
CoordinatedTransform | bool | None
|
Transform pipeline or boolean flag. Pass |
None
|
transforms
|
CoordinatedTransform | bool | None
|
Alias for transform. |
None
|
image_size
|
tuple[int, int]
|
Target |
(640, 640)
|
cache_dir
|
str | Path | None
|
Directory for cache file. |
None
|
use_cache
|
bool
|
Whether to use on-disk caching. |
True
|
bbox_format
|
Literal['xyxy', 'norm_xyxy']
|
Output bbox format ( |
'norm_xyxy'
|
class_names
|
Sequence[str] | None
|
Optional list of class names. |
None
|
Source code in src/corecv/data/datasets/detection.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 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 | |
CACHE_VERSION = 3
class-attribute
¶
Integer version identifier bumped when cache format changes.
SUPPORTED_FORMATS = frozenset({'coco', 'yolo'})
class-attribute
¶
Annotation formats recognised by this dataset.
class_names
property
¶
Return the list of class name strings.
Returns:
| Type | Description |
|---|---|
list[str]
|
Ordered list of class names (index = class id). |
image_paths
property
¶
Return the list of image file paths.
Returns:
| Type | Description |
|---|---|
list[Path]
|
Ordered list of paths, one per sample. |
num_classes
property
¶
Return the number of unique classes.
Returns:
| Type | Description |
|---|---|
int
|
Class count. |
__getitem__(index)
¶
Return the (image, bboxes, labels) tuple at index.
Loads the image from disk and retrieves cached bounding boxes and labels from the in-memory cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Sample index. |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
A tuple |
Tensor
|
|
Tensor
|
|
tuple[Tensor, Tensor, Tensor]
|
|
Source code in src/corecv/data/datasets/detection.py
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 | |
__len__()
¶
Return the number of samples in the dataset.
Returns:
| Type | Description |
|---|---|
int
|
Total sample count. |
Segmentation Datasets¶
corecv.data.datasets.segmentation
¶
Semantic segmentation dataset with on-disk mask loading and cache manifest.
Provides :class:SegmentationDataset for reading paired images and
uint8-indexed masks from images/ and masks/ subdirectories with
matched 1:1 filenames. The dataset implements an O(N) pre-flight check
that validates all annotations and generates a compressed .npz cache
file containing only a manifest of validated pairs with file
modification timestamps — no mask pixel arrays are stored in the cache.
Masks are read from disk dynamically at __getitem__ time, avoiding
memory explosion on large datasets.
Example
from corecv.data.datasets import SegmentationDataset dataset = SegmentationDataset("path/to/data", num_classes=21) image, mask = dataset[0] image.shape torch.Size([3, 480, 640]) mask.shape torch.Size([480, 640])
SegmentationDataset(root, num_classes, transforms=None, transform=None, image_size=None, cache_dir=None, ignore_index=None)
¶
Bases: Dataset[tuple[Tensor, Tensor]]
PyTorch Dataset for semantic segmentation with on-disk mask loading.
Expects the following directory structure under root::
root/
images/
image_001.jpg
image_002.png
...
masks/
image_001.png # uint8, class indices 0..num_classes-1
image_002.png
...
Features:
- 1:1 matched filename pairing between
images/andmasks/. - Masks are validated as uint8 with values in
[0, num_classes)(plus an optionalignore_index). - O(N) pre-flight check generates a
.npzcache on first run. - The cache stores only a manifest of validated pairs with file modification timestamps — no mask pixel arrays are persisted, avoiding memory explosion on large datasets.
- Mask pixel data is read from disk dynamically at
__getitem__time via PIL in uint8 format. - Cache invalidation via filesystem mtime comparison — any change to a source file triggers a rebuild.
- Optional :class:
~corecv.data.transforms.CoordinatedTransformintegration for synchronised image + mask augmentations.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Path
|
Resolved path to the dataset root directory. |
num_classes |
int
|
Number of semantic classes (used for validation). |
transforms |
CoordinatedTransform | None
|
Optional transform pipeline for synchronised image + mask augmentations. |
ignore_index |
int | None
|
Optional label value that is excluded from
range validation (e.g. |
image_paths |
list[Path]
|
List of resolved image file paths. |
mask_paths |
list[Path]
|
List of resolved mask file paths. |
cache_path |
Path
|
Path to the on-disk |
Initialise the dataset, validating pairs and loading / building cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
str | Path
|
Root directory containing |
required |
num_classes
|
int
|
Number of semantic classes. |
required |
transforms
|
CoordinatedTransform | bool | None
|
Transform pipeline or boolean flag. Pass |
None
|
transform
|
CoordinatedTransform | bool | None
|
Alias for transforms. |
None
|
image_size
|
tuple[int, int] | None
|
Target |
None
|
cache_dir
|
str | Path | None
|
Directory for cache file. Defaults to root. |
None
|
ignore_index
|
int | None
|
Optional class index to exclude from range validation. |
None
|
Source code in src/corecv/data/datasets/segmentation.py
cache_path
property
¶
Return the path to the on-disk .npz cache file.
ignore_index
property
¶
Return the optional ignore index.
image_paths
property
¶
Return the list of resolved image file paths.
mask_paths
property
¶
Return the list of resolved mask file paths.
num_classes
property
¶
Return the number of semantic classes.
root
property
¶
Return the dataset root directory.
transforms
property
¶
Return the optional transform pipeline.
__getitem__(index)
¶
Return a single (image, mask) pair at the given index.
Both the image and mask are read from disk dynamically. The
image is returned as a [C, H, W] float32 tensor and the
mask as a [H, W] torch.long tensor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Sample index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
tuple[Tensor, Tensor]
|
A tuple |
Source code in src/corecv/data/datasets/segmentation.py
__len__()
¶
Return the number of samples in the dataset.
Returns:
| Type | Description |
|---|---|
int
|
Total number of valid image-mask pairs. |