# Preprocessing and augmentation

Use preprocessing to define the input the model will see, and augmentation to vary training examples. heliaEDGE provides both through Keras layers, including normalization, filtering, resizing, crops, noise and composed pipelines.

## Start with one transform

After choosing a Keras backend, normalize a batch of signals. This example keeps the `(batch, time, channels)` shape:

```python
import keras
from helia_edge.layers.preprocessing import Normalization1D

signals = keras.ops.ones((2, 128, 1), dtype="float32")
normalize = Normalization1D(mean=0.0, variance=4.0)
normalized = normalize(signals)
```

Every value becomes `0.5`. The mean and variance belong to your data policy; this example supplies them explicitly.

Add training-only noise in a pipeline

Reuse `signals` and `normalize` from above:

```python
from helia_edge.layers.preprocessing import AugmentationPipeline, RandomGaussianNoise1D

pipeline = AugmentationPipeline([
    normalize,
    RandomGaussianNoise1D(factor=0.05, seed=7),
])
training_inputs = pipeline(signals, training=True)
inference_inputs = pipeline(signals, training=False)
```

The training call adds noise after normalization. The inference call only normalizes. Keep `force_training` disabled for a pipeline that will also run at inference.

## Choose the transformation

| Goal | Components | Important behavior |
|---|---|---|
| Normalize signal values | Normalization1D/2D, LayerNormalization1D/2D | Check the axis, layout and compute dtype. |
| Filter a signal | FirFilter, CascadedBiquadFilter | Check each filter's coefficient and execution contract. |
| Resize or crop | Resizing1D/2D, RandomCrop1D/2D | Keep selected targets and masks aligned with the signal. |
| Add training variation | RandomGaussianNoise1D, AmplitudeWarp, RandomCutout1D/2D, SpecAugment2D | Pass the training flag explicitly; transforms differ in what they preserve. |
| Compose transforms | AugmentationPipeline, RandomChoice, random augmentation pipelines | Branches must produce compatible structures, dtypes and shapes. |

[Preprocessing API](https://ambiqai.github.io/helia-edge/reference/api/helia_edge/layers/preprocessing/)
[Search all components](https://ambiqai.github.io/helia-edge/reference/)

## Represent a sample

`Sample` groups tensors into `signals`, `targets` and `masks`. Pass `sample.tensor_tree()` to a Keras layer. Keep record IDs and other metadata outside that tree. Conversion creates fresh dictionaries but references the existing tensors; it does not copy tensor storage.

[Structured-sample walkthrough](https://ambiqai.github.io/helia-edge/guide/portable-preprocessing/)

Advanced: alignment, shapes and custom transforms

Training-only transforms use `training=True` to apply augmentation. Deterministic transforms can also run at inference. A random crop may shorten training inputs while leaving inference inputs unchanged, so choose a separate deterministic inference window when your model requires a fixed shape.

For geometric transforms, select which target and mask keys share the signal transformation. Resizing aligned targets requires an explicit interpolation policy: categorical labels need nearest selection; signal-valued targets need the signal policy. Masks retain their label dtype.

When writing a custom transform, follow the hook, RNG, alignment and shape contracts.

[Preprocessing contracts](https://ambiqai.github.io/helia-edge/guide/preprocessing-contracts/)
