GroupNormalization#

GroupNormalization - 18#

Version

  • name: GroupNormalization (GitHub)

  • domain: main

  • since_version: 18

  • function: False

  • support_level: SupportType.COMMON

  • shape inference: False

This version of the operator has been available since version 18.

Summary

A GroupNormalization function. Carries out group normalization as described in the paper https://arxiv.org/abs/1803.08494

This operator transforms input according to

y = scale * (x - mean) / sqrt(variance + epsilon) + bias,

where the mean and variance are computed per instance per group of channels, and scale and bias should be specified for each group of channels. The number of groups num_groups should be divisible by the number of channels so that there are an equal number of channels per group.

When the number of groups is the same as the number of channels, this operator is equivalent to InstanceNormalization. When there is only one group, this operator is equivalent to LayerNormalization.

Attributes

  • epsilon: The epsilon value to use to avoid division by zero. Default value is 9.999999747378752e-06.

  • num_groups (required): The number of groups of channels. It should be a divisor of the number of channels C.

Inputs

  • X (heterogeneous) - T: Input data tensor. Dimensions for image cases are (N x C x H x W), where N is the batch size, C is the number of channels, and H and W are the height and width of the data. Statistics are computed for every group of channels over C, H, and W. For non-image cases, the dimensions are in the form of (N x C x D1 x D2 … Dn).

  • scale (heterogeneous) - T: Scale tensor of shape (num_groups).

  • bias (heterogeneous) - T: Bias tensor of shape (num_groups).

Outputs

  • Y (heterogeneous) - T: The output tensor of the same shape as X.

Type Constraints

  • T in ( tensor(bfloat16), tensor(double), tensor(float), tensor(float16) ): Constrain input and output types to float tensors.

Examples

default

x = np.random.randn(3, 4, 2, 2).astype(np.float32)
num_groups = 2
scale = np.random.randn(num_groups).astype(np.float32)
bias = np.random.randn(num_groups).astype(np.float32)
y = _group_normalization(x, num_groups, scale, bias).astype(np.float32)

node = onnx.helper.make_node(
    "GroupNormalization",
    inputs=["x", "scale", "bias"],
    outputs=["y"],
    num_groups=num_groups,
)

expect(
    node,
    inputs=[x, scale, bias],
    outputs=[y],
    name="test_group_normalization_example",
)

x = np.random.randn(3, 4, 2, 2).astype(np.float32)
num_groups = 2
scale = np.random.randn(num_groups).astype(np.float32)
bias = np.random.randn(num_groups).astype(np.float32)
epsilon = 1e-2
y = _group_normalization(x, num_groups, scale, bias, epsilon).astype(np.float32)

node = onnx.helper.make_node(
    "GroupNormalization",
    inputs=["x", "scale", "bias"],
    outputs=["y"],
    epsilon=epsilon,
    num_groups=num_groups,
)

expect(
    node,
    inputs=[x, scale, bias],
    outputs=[y],
    name="test_group_normalization_epsilon",
)