Normalizer Reference¤
Data normalization is essential for the stable and efficient training of Neural Operators. Skewed training data distributions heavily influence model performance and training, especially for physical data which may range across vastly different scales. neojax provides multiple normalizers for reliable training.
All normalizers share a common API, inherit from BaseNormalizer, and can be arbitrarily composed to build complex normalization pipelines.
The Normalizer API¤
We adopt the common naming conventions of scientific computing libraries. Every normalizer implements:
compute_stats(data, axis=...): 'Learns' the normalization statistics (e.g., min/max, mean/std) from the given data. Becauseneojaxusesequinoxand is strictly functional, this returns a new normalizer instance with the updated statistics.transform(x)/__call__(x): Applies the normalization to the input.inverse_transform(x): Reverses the normalization, projecting predictions back into the original physical space.
Example Usage¤
import jax.numpy as jnp
from neojax.data.normalizers import MinMaxNormalizer
# 1. Initialize the normalizer
normalizer = MinMaxNormalizer()
# 2. Learn statistics from training data
train_data = jnp.array([[-10.0, 0.0, 10.0]])
normalizer = normalizer.compute_stats(train_data)
# 3. Transform data before passing to the model
normalized_data = normalizer(train_data)
# normalized_data is now scaled to [0, 1]
# 4. Revert model predictions back to the original scale
predictions = model(normalized_data)
physical_predictions = normalizer.inverse_transform(predictions)
Composing Normalizers¤
Data pipelines often require multiple transformation steps. The ComposedNormalizer allows you to pipe normalizers together.
By default, compute_stats works sequentially through the pipeline: the second normalizer computes its statistics on the data after it has been transformed by the first normalizer. You can disable this by passing sequential=False.
from neojax.data.normalizers import ComposedNormalizer, RobustNormalizer, MinMaxNormalizer
# Build a pipeline
pipeline = ComposedNormalizer(
RobustNormalizer(),
MinMaxNormalizer()
)
# Computes robust stats, transforms data, then computes min/max stats on the output
pipeline = pipeline.compute_stats(data)
Base Normalizer¤
neojax.data.normalizers.base_normalizer.BaseNormalizer
¤
Base class for all normalizers.
All normalizers should inherit from BaseNormalizer. Following the "Abstract or Final" pattern, this class contains no logic and only defines the interface. Subclasses should be marked as final.
Normalizer methods follow the naming conventions of major
libraries, where transform is the forward operation
and inverse_transform the inverse.
Internal Attributes
These fields store the internal state of the normalizer.
- stats (
PyTree): A PyTree containing the normalization statistics (e.g. mean, std).
compute_stats(data: Float[Array, ...]) -> BaseNormalizer
¤
Computes statistics from the provided data.
This function should set the stats attribute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, ...]
|
The data to compute statistics from. |
required |
Returns:
| Type | Description |
|---|---|
BaseNormalizer
|
A new BaseNormalizer instance with updated stats. |
transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Applies the forward normalization transform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The transformed array. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Applies the inverse normalization transform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The transformed array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The array in its original scale |
Unit Gaussian Normalizer¤
neojax.data.normalizers.unit_gaussian_normalizer.UnitGaussianNormalizer
¤
Normalizes data to be mean zero and unit std.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mean
|
float | Float[Array, ...]
|
Optional initial mean if known. Default is 0.0. |
0.0
|
std
|
float | Float[Array, ...]
|
Optional initial standard deviation if known. Default is unit 1.0. |
1.0
|
Internal Attributes
These fields store the internal state of the normalizer.
- stats (
dict[str, Float[Array, ...] | None]): Dict of mean and std.
mean
property
¤
Accessor for the mean stored in stats.
std
property
¤
Accessor for the std stored in stats.
compute_stats(data: Float[Array, 'c ...'], axis: int | tuple[int, ...] | None = None) -> UnitGaussianNormalizer
¤
Computes mean and std from diven data.
To normalize per-channel for input (c, d1, ..., dN), pass axis=tuple(range(1, data.ndim)). To normalize across all axes, pass axis=None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, 'c ...']
|
The input array. |
required |
axis
|
int | tuple[int, ...] | None
|
Axis or axes along which the statistics are computed. The default (None) computes the global mean/std. |
None
|
Returns:
| Type | Description |
|---|---|
UnitGaussianNormalizer
|
A new UnitGaussianNormalizer instance |
UnitGaussianNormalizer
|
with updated mean and std. |
transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Standardizes input using stored mean and std.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The standardized array. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Reverts standardization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The standardized array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The de-standardized array. |
Robust Normalizer¤
neojax.data.normalizers.robust_normalizer.RobustNormalizer
¤
Normalizes data using median and interquartile range.
This normalizer is robust to outliers as it uses the median and the interquartile range (IQR).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
median
|
float | Float[Array, ...] | None
|
Optional median for dynamical scaling.
Default is None, i.e., use learned median from |
None
|
scale
|
float | Float[Array, ...] | None
|
Optional interquartile range for dynamical scaling.
Default is None, i.e., use learned iqr from |
None
|
quantile_range
|
tuple[float, float]
|
|
(25.0, 75.0)
|
Internal Attributes
These fields store the internal state of the normalizer.
- quantile_range (
tuple[float, float]): The lower and upper quantile bounds. - stats (
dict[str, Float[Array, ...] | None]): Dict containing 'median' and 'scale' (iqr).
median
property
¤
Accessor for the median stored in stats.
scale
property
¤
Accessor for the scale stored in stats.
compute_stats(data: Float[Array, 'c ...'], axis: int | tuple[int, ...] | None = None) -> RobustNormalizer
¤
Computes median and quantile range from given data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, 'c ...']
|
The input array to compute statistics from. |
required |
axis
|
int | tuple[int, ...] | None
|
Axis or axes along which the statistics are computed. The default (None) computes the global statistics. |
None
|
Returns:
| Type | Description |
|---|---|
RobustNormalizer
|
A new RobustNormalizer instance with updated statistics. |
transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Normalizes input using median and quantile range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The normalized array. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Reverts robust normalization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The transformed array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The de-normalized array. |
Min/Max Normalizer¤
(Supports both "scale" and destructive "clip" modes)
neojax.data.normalizers.min_max_normalizer.MinMaxNormalizer
¤
Normalizes data to be within a given min and max.
Minima and maxima can be passed the following ways:
- During initialization if known or explicitly required (e.g. known physical bounds).
- Learned from data by passing them to
compute_stats
Data can be clipped or scaled to [min, max] range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
minima
|
float | int | Float[Array, ...] | None
|
Optional min for dynamical scaling.
Default is None, i.e., use learned min
from |
None
|
maxima
|
float | int | Float[Array, ...] | None
|
Optional max for dynamical scaling.
Default is None, i.e., use learned max
from |
None
|
Internal Attributes
These fields store the internal state of the normalizer.
- stats (
dict[str, Float[Array, ...] | None]): Dict of min and max if passed at initialization, else None.
Warning
Inverse transformation can only be applied for scaled transformations.
maxima
property
¤
Accessor for the max stored in stats.
minima
property
¤
Accessor for the min stored in stats.
compute_stats(data: Float[Array, 'c ...'], axis: int | tuple[int, ...] | None = None) -> MinMaxNormalizer
¤
Computes min and max from given data.
To normalize per-channel for input (c, d1, ..., dN), pass axis=tuple(range(1, data.ndim)). To normalize across all axes, pass axis=None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, 'c ...']
|
The input array. |
required |
axis
|
int | tuple[int, ...] | None
|
Axis or axes along which the statistics are computed. The default (None) computes the global min/max. |
None
|
Returns:
| Type | Description |
|---|---|
MinMaxNormalizer
|
A new MinMaxNormalizer instance |
MinMaxNormalizer
|
with updated min and max. |
transform(x: Float[Array, ...], mode: typing.Literal['clip', 'scale'] = 'scale') -> Float[Array, ...]
¤
Normalizes input by clipping or rescaling it.
Uses learned minima or maxima from self.stats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
mode
|
Literal['clip', 'scale']
|
Whether to |
'scale'
|
Note
"clip" is a destructive operation. Clipped data cannot be
perfectly reconstructed:
inverse_transform(transform(x, mode="clip", ...), ...) != x
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The min/max normalized array. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the transformation mode is unsupported. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Reverts scaled min/max normalization.
Can only reverse scaled normalization. Clipped normalizations are irreversible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The standardized array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The de-normalized array. |
Physics Normalizer¤
(Non-dimensionalizes data using physical scales. See Scales Reference.)
neojax.data.normalizers.physics_normalizer.PhysicsNormalizer
¤
Normalizes data based on spatial dimensions/physical units.
This normalizer applies a product of multiple PhysicalScale factors
to non-dimensionalize the input data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*scales
|
PhysicalScale
|
Variable number of |
required |
Internal Attributes
These fields store the internal state of the normalizer.
- scales (
tuple[PhysicalScale, ...]): Tuple of physical scale providers. - stats (
dict[str, Float[Array, ...] | None]): Dict containing 'scale_product', which is the resulting element-wise product of all computed scales.
Examples:
from neojax.data.scales import CharacteristicLengthScale, ReynoldsScale
# Compose multiple physical scales
norm = PhysicsNormalizer(
CharacteristicLengthScale(L_ref=1.0),
ReynoldsScale(U=10.0, L=1.0, nu=1e-3)
)
# Compute and apply
norm = norm.compute_stats(data)
non_dimensional = norm(data)
compute_stats(data: Float[Array, 'c ...'], axis: int | tuple[int, ...] | None = None) -> PhysicsNormalizer
¤
Computes the product of all scales for the given data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, 'c ...']
|
The input array to compute statistics from. |
required |
axis
|
int | tuple[int, ...] | None
|
Unused for physics-based scaling but kept for API compatibility. |
None
|
Returns:
| Type | Description |
|---|---|
PhysicsNormalizer
|
A new PhysicsNormalizer instance with the final computed |
PhysicsNormalizer
|
scale product in |
transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Non-dimensionalizes input by dividing by the scale product.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The non-dimensionalized array. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Reverts non-dimensionalization by multiplying by the scale product.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The transformed array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The array in physical units. |
Composed Normalizer¤
neojax.data.normalizers.composed_normalizer.ComposedNormalizer
¤
Composes multiple normalizers into a pipeline.
The normalizers are applied sequentially in the order they are provided. This class allows for complex normalization pipelines, such as first applying a robust scaler and then a min-max scaling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*normalizers
|
BaseNormalizer
|
Normalizer instances to be composed in the pipeline. |
required |
Internal Attributes
These fields store the internal state of the normalizer.
- stats (
dict[str, tuple[BaseNormalizer, ...]]): Dict containing 'normalizers', which stores the sequence of normalizers as a tuple.
Examples:
import jax.numpy as jnp
from neojax.data.normalizers import (
ComposedNormalizer,
MinMaxNormalizer,
UnitGaussianNormalizer
)
norm = ComposedNormalizer(
MinMaxNormalizer(),
UnitGaussianNormalizer()
)
data = jnp.ones((3, 3, 3))
# compute stats (sequentially)
norm = norm.compute_stats(data)
transformed = norm(data)
Notes
If all normalizer statistics need to be computed on raw data,
pass sequential=False to compute_stats().
compute_stats(data: Float[Array, 'c ...'], axis: int | tuple[int, ...] | None = None, sequential: bool = True) -> ComposedNormalizer
¤
Computes statistics for each normalizer in the pipeline.
Each normalizer in the pipeline computes its statistics
independently based on the provided data, either sequentially
of non-sequentially. See sequential for details.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Float[Array, 'c ...']
|
The input array to compute statistics from. |
required |
axis
|
int | tuple[int, ...] | None
|
Axis or axes along which the statistics are computed. The default (None) computes the global statistics. |
None
|
sequential
|
bool
|
Whether to apply stats computations in sequence, i.e., compute the stats on the transformed inputs of the previous normalizer. Non-sequential computes each stat on the raw inputs (e.g. for parallel computation). Default is sequential. |
True
|
Returns:
| Type | Description |
|---|---|
ComposedNormalizer
|
A new ComposedNormalizer instance with updated statistics |
ComposedNormalizer
|
for all sub-normalizers. |
transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Applies the sequence of normalizations to the input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The input array to transform. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The transformed array. |
inverse_transform(x: Float[Array, ...]) -> Float[Array, ...]
¤
Reverts the sequence of normalizations in reverse order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Float[Array, ...]
|
The transformed array to revert. |
required |
Returns:
| Type | Description |
|---|---|
Float[Array, ...]
|
The de-normalized array. |