归一化

在轴集合上归一化输入张量。通用归一化方程为

\(Y=\frac{ X - Mean(X, axes) }{ \sqrt{Var(X, axes) + epsilon } } * S + B\)

其中

X 是输入张量

Y 是输出张量

Mean(X, axes) 是输入在提供的轴集合上的均值

Var(X, axes) 是输入在提供的轴集合上的方差

S 是缩放张量

B 是偏差张量

属性

epsilon 归一化中使用的 epsilon 值,以避免除以 0。

axes 执行归一化的轴。

num_groups 归一化的组数。如果 num_groups != 1,则输入通道将在执行归一化之前拆分为 num_groups

compute_precision 执行归一化计算的精度。

输入

input: 类型为 T1 的张量

scale: 类型为 T1 的张量

bias: 类型为 T1 的张量

输出

output: 类型为 T1 的张量

数据类型

T1: float32, float16, bfloat16

形状信息

根据归一化操作的类型,预期的输入形状会有所不同。

InstanceNormalization

对于图像输入,输入形状应为 \([N, C, H, W, ...]\),对于非图像输入,输入形状应为 \([N, C, D1, ...]\)

Scale 和 Bias 形状应为 \([1, C, 1, 1, ..., 1]\),其中 C 是输入张量的通道数。

输出形状应为 \([N, C, H, W, ...]\)\([N, C, D1, ...]\)

GroupNormalization

对于图像输入,输入形状应为 \([N, C, H, W, ...]\),对于非图像输入,输入形状应为 \([N, C, D1, ...]\)

Scale 和 Bias 形状应为 \([1, G, 1, 1, ..., 1]\),其中 G 是组数。

输出形状应为 \([N, C, H, W, ...]\)\([N, C, D1, ...]\)

LayerNormalization

输入形状应为 \([D0, D1, D2, D3, ..., DN]\)

Scale 和 Bias 形状取决于提供的轴。

例如,对于轴 \([2, 3, ... N]\),Scale 和 Bias 形状应为 \([1, 1, D2, D3, ..., DN]\)

对于轴 \([3, ... N]\),Scale 和 Bias 形状应为 \([1, 1, 1, D3, ..., DN]\)

输出形状应为 \([D0, D1, D2, D3, ..., DN]\)

示例

def convert_axes_to_tuple(axes, num_dims):
    converted_axes = []
    for i in range(num_dims):
        ref = 1 << i
        if axes & ref == ref:
            converted_axes.append(i)
    return tuple(converted_axes)

def normalization_reference(x, s, bias, axes, epsilon=1e-5):  # type: ignore
    num_dims = len(x.shape)
    converted_axes = convert_axes_to_tuple(axes, num_dims)
    mean = np.mean(x, axis=converted_axes, keepdims=True)
    var = np.var(x, axis=converted_axes, keepdims=True)
    return s * (x - mean) / np.sqrt(var + epsilon) + bias

input = network.add_input("input1", dtype=trt.float32, shape=(2, 3, 2, 2))
scale = network.add_input("scale", dtype=trt.float32, shape=(1, 3, 1, 1))
bias = network.add_input("bias", dtype=trt.float32, shape=(1, 3, 1, 1))

axes = 1 << 2 | 1 << 3
layer = network.add_normalization(input, scale, bias, axes)
network.mark_output(layer.get_output(0))

input_vals = np.random.rand(2, 3, 2, 2)
scale_vals = np.array([1.0, 2.0, 3.0]).reshape((1, 3, 1, 1))
bias_vals = np.array([-3.0, -2.0, -1.0]).reshape((1, 3, 1, 1))

inputs[input.name] = input_vals
inputs[scale.name] = scale_vals
inputs[bias.name] = bias_vals

outputs[layer.get_output(0).name] = layer.get_output(0).shape

ref = normalization_reference(input_vals, scale_vals, bias_vals, axes)

expected[layer.get_output(0).name] = ref

C++ API

有关 C++ INormalization 算子的更多信息,请参阅 C++ INormalization 文档

Python API

有关 Python INormalization 算子的更多信息,请参阅 Python INormalization 文档