Core API¶
Compose is the main public entry point. It accepts a list of recognized backend transform objects and builds a segmented torch.nn.Module around the supported (B, C, H, W) tensor contract.
Compose and FusedCompose refer to the same class. AugmentationSequential is another naming alias; these aliases do not imply complete behavioral compatibility with every native container option.
Choose a construction style¶
import torch
import torchvision.transforms.v2 as transforms
from fuse_augmentations import Compose
pipe = Compose(
[
transforms.RandomRotation(15),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomAffine(degrees=0, scale=(0.9, 1.1)),
],
)
image = torch.rand(8, 3, 224, 224)
output = pipe(image)
print(pipe.fusion_plan)
Fusion plan for the native TorchVision pipeline
Use Compose.from_params for an augmentation-backend-free pipeline and Compose.from_config for declarative backend-specific construction. Both are documented in Configuration API.
Input and output forms¶
The standard call accepts a BCHW tensor. Set data_keys when positional auxiliary targets are present:
Use only explicitly supported spatial transforms with auxiliary targets
With auxiliary data_keys, an unknown or unclassified spatial transform is rejected before any segment executes. Image-only calls may use native passthrough, so review every Unknown ... SPATIAL_KERNEL barrier warning. Read Auxiliary targets before using this path for training data.
import torch
import torchvision.transforms.v2 as transforms
from fuse_augmentations import Compose
safe_transforms = [
transforms.RandomRotation(15),
transforms.RandomHorizontalFlip(p=0.5),
]
pipe = Compose(
safe_transforms,
data_keys=["input", "mask", "bbox_xyxy", "keypoints"],
)
image = torch.rand(2, 3, 64, 64)
mask = torch.zeros(2, 1, 64, 64, dtype=torch.long)
boxes = torch.tensor([[[8.0, 8.0, 32.0, 32.0]]] * 2)
keypoints = torch.tensor([[[16.0, 16.0]]] * 2)
image_out, mask_out, boxes_out, keypoints_out = pipe(
image,
mask,
boxes,
keypoints,
)
output_backend="numpy" converts images and masks to channel-last NumPy arrays. Coordinate outputs remain tensors.
An image-only Albumentations pipeline additionally accepts pipe(image=hwc_array) and returns an Albumentations-style dictionary. Auxiliary keyword keys are not supported on that native NumPy path; use tensor inputs and data_keys instead.
For detector batches whose per-image annotations are ragged, use the package-root augment_detection_batch boundary rather than padding targets in application code.
Inspect a pipeline¶
for descriptor in pipe.fusion_plan_descriptors:
print(descriptor.kind, descriptor.transforms, descriptor.n_warps_saved)
output, last_matrix = pipe(image, return_matrix=True)
Segment descriptor and saved warp count for the pipeline
fusion_plan, fusion_plan_descriptors, and n_warps_saved describe the constructed plan. transform_matrix and return_matrix=True report the actual forward pixel-centre matrix from the most recent call's last supported matrix-producing segment. Fused affine/projective, exact D4/flip/quarter-turn, and direct deterministic letterbox segments publish it; it is not a whole-pipeline composition.
Constructor options that change semantics¶
| Option | Effect |
|---|---|
reorder |
Preserves order by default; POINTWISE may move color operations to extend geometric runs |
randomness |
Preserves backend sampling by default; per_sample requests independent draws where supported |
execution |
Selects cv2 or torch execution for fused Albumentations geometry only |
interpolation, padding_mode |
Segment-level sampling choices for fused geometry |
clip_policy |
Controls boundaries/clamping in fused color runs |
mask_interpolation |
nearest for hard labels or bilinear for floating soft masks |
compile |
Opts eligible non-CPU torch warp cores into torch.compile |
antialias |
Enables supported downscale prefiltering |
substitute_passthrough |
Opts into behavior-changing registered passthrough substitutions |
pipeline_dtype |
"bfloat16" or "float16" low-precision execution for fused warp/color/LUT cores; default None |
Extra backend_kwargs are currently reserved and unused; do not rely on them as an extension mechanism.
Compose / FusedCompose¶
FusedCompose ¶
FusedCompose(transforms: list[object], reorder: ReorderPolicy = NONE, interpolation: InterpolationStr | None = None, padding_mode: ComposePaddingModeStr | None = None, data_keys: list[str] | None = None, output_backend: Literal['numpy', 'numpy_hwc', 'torch'] | None = None, randomness: RandomnessPolicy | Literal['backend', 'per_sample'] = BACKEND, execution: ExecutionStr = 'cv2', compile: bool = False, antialias: bool = False, substitute_passthrough: bool = False, clip_policy: ClipPolicyStr = 'final', mask_interpolation: MaskInterpolationStr = 'nearest', pipeline_dtype: PipelineDtypeStr | None = None, generator: Generator | None = None, fill: FillValue | None = None, keypoint_flip_index: Sequence[int] | None = None, mask_fill: MaskFillValue = 0, **backend_kwargs: object)
Bases: FactoriesMixin, IntrospectionMixin, GeneratorPicklingMixin, Module
Fused augmentation pipeline that replaces the backend's native Compose.
Segments the transform list into fused geometric segments and passthrough transforms, then executes them sequentially. Consecutive geometric ops are grouped and executed as either:
- A :class:
~fuse_augmentations.affine.segment.FusedAffineSegment- when the run contains at least oneGEOMETRIC_INTERPop. Matrices are composed and a singlegrid_samplecall is used, eliminating redundant interpolation passes. - An :class:
~fuse_augmentations.affine.segment.ExactAffineSegment- when the run contains onlyGEOMETRIC_EXACTops (HFlip, VFlip). Transforms are applied viatensor.flipwith zero interpolation error.
SPATIAL_KERNEL and nonlinear POINTWISE transforms are passed through
to the backend adapter unchanged. Supported POINTWISE_LINEAR color
transforms, including standard Normalize, are folded into a color segment.
ReorderPolicy.POINTWISE is fully implemented: before segmentation,
POINTWISE and POINTWISE_LINEAR ops are bubbled past geometric ops
within each SPATIAL_KERNEL-bounded stretch, maximising the geometric
run length available for fusion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
transforms
|
list[object]
|
List of augmentation transform objects. |
required |
reorder
|
ReorderPolicy
|
Reorder policy applied before segmentation.
|
NONE
|
interpolation
|
InterpolationStr | None
|
Interpolation mode override for fused segments
( |
None
|
padding_mode
|
ComposePaddingModeStr | None
|
Padding mode override for fused segments
( |
None
|
data_keys
|
list[str] | None
|
List of key names describing positional arguments to
:meth: |
None
|
output_backend
|
Literal['numpy', 'numpy_hwc', 'torch'] | None
|
Target output format. |
None
|
randomness
|
RandomnessPolicy | Literal['backend', 'per_sample']
|
Batch randomness policy. |
BACKEND
|
execution
|
ExecutionStr
|
Warp strategy for the Albumentations fused segments.
|
'cv2'
|
compile
|
bool
|
Opt-in |
False
|
antialias
|
bool
|
Opt-in antialiasing for aggressive downscales. Off by default.
When |
False
|
substitute_passthrough
|
bool
|
When |
False
|
clip_policy
|
ClipPolicyStr
|
Clamp policy for fused color segments. |
'final'
|
mask_interpolation
|
MaskInterpolationStr
|
Auxiliary mask sampling mode. |
'nearest'
|
mask_fill
|
MaskFillValue
|
Scalar auxiliary-mask border value, independent of image fill. Defaults
to zero; use a dtype-compatible ignore label such as |
0
|
pipeline_dtype
|
PipelineDtypeStr | None
|
Optional |
None
|
keypoint_flip_index
|
Sequence[int] | None
|
Keypoint pair permutation applied to the |
None
|
fill
|
FillValue | None
|
Constant value written outside the source canvas of every resampling
warp, in the image's own value range ( |
None
|
generator
|
Generator | None
|
Caller-owned |
None
|
**backend_kwargs
|
object
|
Reserved for backend-specific options (currently unused). |
{}
|
Initialize FusedCompose.
forward ¶
Apply the augmentation pipeline to an image batch and optional auxiliary targets.
Single-tensor mode (data_keys=None, default): accepts one image
tensor and returns one tensor or a NumPy ndarray when
output_backend="numpy". This is the backward-compatible path.
Multi-target mode (data_keys is set): accepts positional
arguments in the same order as data_keys. The first key must map
to the image ("input"); subsequent keys are auxiliary targets
("mask", "bbox_xyxy", "bbox_xywh", "keypoints").
Returns a tuple of tensors in data_keys order, or a bare tensor
when data_keys contains exactly one entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*args
|
Tensor
|
Positional tensors matching the |
()
|
return_matrix
|
bool
|
When |
False
|
**kwargs
|
object
|
Declared multi-target keyword inputs. Tensor keyword calls return a dict and retain the same public module hooks as positional tensor calls. |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
Single |
object
|
|
object
|
|
object
|
|
object
|
When |
object
|
|
object
|
geometric segment, or |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the number of positional arguments does not match
the number of |
Note
Only known coordinate-preserving passthrough transforms may run with auxiliary targets. Unclassified or coordinate-changing passthrough is refused before any segment executes, since it cannot route the targets.
output_backend conversion is applied per target in multi-target
mode: image and mask outputs are converted to the requested backend,
while coordinate targets (boxes, keypoints) remain tensors because the
channel-last image layout does not apply to them.
inverse ¶
Map a paired augmented tensor back to its original geometric frame.
Pass the matrix returned by the exact paired forward(...,
return_matrix=True) call. This avoids reading :attr:transform_matrix,
which is mutable compatibility state and therefore unsafe to pair with an
output from another concurrent call. The method supports one fused affine
or projective segment, including a chain already fused into that segment.
It applies one grid_sample to the image and routes declared masks,
boxes, and keypoints through the inverse pixel matrix.
Keypoints and masks recover to sampling precision. Bounding boxes are axis-aligned (AABB), so a forward-then-inverse box is exact only for axis-aligned transforms (flip, scale, translation) and inflates under a rotation, shear, or projective warp. The matrix is not validated against the paired image: a matrix from a different call yields silently wrong geometry, so always pass the matrix returned by the same forward call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Tensor
|
Augmented |
required |
*auxiliary_targets
|
Tensor
|
Augmented targets in |
()
|
matrix
|
Tensor | None
|
Forward pixel matrix returned by the paired forward call. |
None
|
Returns:
| Type | Description |
|---|---|
object
|
The de-augmented image, or a tuple in |
object
|
auxiliary targets are supplied. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the image or matrix has an unsupported tensor shape or dtype. |
ValueError
|
If the pipeline has a non-invertible segment, no paired
matrix, or targets that do not match |
Examples:
>>> import torch
>>> from fuse_augmentations import Compose
>>> pipe = Compose.from_params(translate_x=(2.0, 2.0))
>>> image = torch.rand(1, 3, 8, 8)
>>> augmented, matrix = pipe(image, return_matrix=True)
>>> recovered = pipe.inverse(augmented, matrix=matrix)
>>> recovered.shape
torch.Size([1, 3, 8, 8])
NumPy converters¶
The converters are useful when conversion should be explicit rather than attached to a pipeline.
NumpyToTorchConverter ¶
Convert NumPy HWC/BHWC arrays to (batch_size, channels, height, width) torch tensors.
All pipeline outputs are (batch_size, channels, height, width) torch.Tensor regardless of backend. uint8
inputs are normalised to float32 in [0, 1] (÷255); uint16 likewise (÷65535); float32 inputs are
passed through unchanged. Any other dtype (float64, float16, signed integers) is cast to float32 WITHOUT
rescaling — values keep their original range.
convert ¶
Convert a NumPy array (HW/HWC/BHWC) to a float32 torch tensor (BCHW).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
array
|
NDArray[Any]
|
NumPy array in channel-last layout:
|
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
|
Tensor
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
TorchToNumpyConverter ¶
Convert (batch_size, channels, height, width) torch tensors to NumPy HWC/BHWC arrays.
Single-image batches (1, channels, height, width) are squeezed to (height, width, channels) for convenience.
Multi-image batches produce (batch_size, height, width, channels).
convert ¶
Convert a torch tensor (BCHW) to a NumPy array (HWC or BHWC).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tensor
|
Tensor
|
|
required |
Returns:
| Type | Description |
|---|---|
NDArray[Any]
|
NumPy |
NDArray[Any]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Ragged detection adapter¶
augment_detection_batch ¶
augment_detection_batch(pipeline: FusedCompose, images: Tensor, targets: Sequence[Mapping[str, Tensor]], *, min_size: float = 0.0, min_visibility: float = 0.0) -> tuple[Tensor, list[dict[str, Tensor]]]
Augment a detector batch while keeping supported ragged target fields aligned.
The pipeline must declare exactly ["input", "bbox_xyxy"]. Each target
requires floating boxes of shape (N, 4) and int64 labels of shape
(N,) on the image device; area, iscrowd, and scalar image_id
are optional. The returned list contains new dictionaries and tensors: boxes
are clipped to the output pixel-edge canvas, positive-area instances meeting
the explicit thresholds survive, labels/iscrowd follow the same mask,
and supplied area is recomputed from the clipped boxes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pipeline
|
FusedCompose
|
A :class: |
required |
images
|
Tensor
|
Floating image batch with shape |
required |
targets
|
Sequence[Mapping[str, Tensor]]
|
One supported detector target mapping per image. |
required |
min_size
|
float
|
Minimum clipped width and height in pixels. |
0.0
|
min_visibility
|
float
|
Minimum clipped/original box-area ratio in |
0.0
|
Returns:
| Type | Description |
|---|---|
Tensor
|
The augmented image batch and one ragged, detector-ready target mapping |
list[dict[str, Tensor]]
|
per input image. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the pipeline, images, targets, or thresholds have an incompatible type. |
ValueError
|
If target schemas, devices, dtypes, fields, or the pipeline declaration are incompatible with this boundary. |