Files
zeekayandHanzo Dev f84fe1fd15 snapshot slice 1
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 15:29:05 -07:00

138 lines
4.6 KiB
Python

# Copyright (c) ONNX Project Contributors
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import numpy as np
import onnx
from onnx.backend.test.case.base import Base
from onnx.backend.test.case.node import expect
def _batchnorm_test_mode(x, s, bias, mean, var, epsilon=1e-5):
dims_x = len(x.shape)
dim_ones = (1,) * (dims_x - 2)
s = s.reshape(-1, *dim_ones)
bias = bias.reshape(-1, *dim_ones)
mean = mean.reshape(-1, *dim_ones)
var = var.reshape(-1, *dim_ones)
return s * (x - mean) / np.sqrt(var + epsilon) + bias
def _batchnorm_training_mode(x, s, bias, mean, var, momentum=0.9, epsilon=1e-5):
axis = tuple(np.delete(np.arange(len(x.shape)), 1))
saved_mean = x.mean(axis=axis)
saved_var = x.var(axis=axis)
output_mean = mean * momentum + saved_mean * (1 - momentum)
output_var = var * momentum + saved_var * (1 - momentum)
y = _batchnorm_test_mode(x, s, bias, saved_mean, saved_var, epsilon=epsilon)
return y.astype(np.float32), output_mean, output_var
class BatchNormalization(Base):
@staticmethod
def export() -> None:
# input size: (2, 3, 4, 5)
x = np.random.randn(2, 3, 4, 5).astype(np.float32)
s = np.random.randn(3).astype(np.float32)
bias = np.random.randn(3).astype(np.float32)
mean = np.random.randn(3).astype(np.float32)
var = np.random.rand(3).astype(np.float32)
y = _batchnorm_test_mode(x, s, bias, mean, var).astype(np.float32)
node = onnx.helper.make_node(
"BatchNormalization",
inputs=["x", "s", "bias", "mean", "var"],
outputs=["y"],
)
# output size: (2, 3, 4, 5)
expect(
node,
inputs=[x, s, bias, mean, var],
outputs=[y],
name="test_batchnorm_example",
)
# input size: (2, 3, 4, 5)
x = np.random.randn(2, 3, 4, 5).astype(np.float32)
s = np.random.randn(3).astype(np.float32)
bias = np.random.randn(3).astype(np.float32)
mean = np.random.randn(3).astype(np.float32)
var = np.random.rand(3).astype(np.float32)
epsilon = 1e-2
y = _batchnorm_test_mode(x, s, bias, mean, var, epsilon).astype(np.float32)
node = onnx.helper.make_node(
"BatchNormalization",
inputs=["x", "s", "bias", "mean", "var"],
outputs=["y"],
epsilon=epsilon,
)
# output size: (2, 3, 4, 5)
expect(
node,
inputs=[x, s, bias, mean, var],
outputs=[y],
name="test_batchnorm_epsilon",
)
@staticmethod
def export_train() -> None:
# input size: (2, 3, 4, 5)
x = np.random.randn(2, 3, 4, 5).astype(np.float32)
s = np.random.randn(3).astype(np.float32)
bias = np.random.randn(3).astype(np.float32)
mean = np.random.randn(3).astype(np.float32)
var = np.random.rand(3).astype(np.float32)
# using np.bool(1) while generating test data with "'bool' object has no attribute 'dtype'"
# working around by using np.byte(1).astype(bool)
training_mode = 1
y, output_mean, output_var = _batchnorm_training_mode(x, s, bias, mean, var)
node = onnx.helper.make_node(
"BatchNormalization",
inputs=["x", "s", "bias", "mean", "var"],
outputs=["y", "output_mean", "output_var"],
training_mode=training_mode,
)
# output size: (2, 3, 4, 5)
expect(
node,
inputs=[x, s, bias, mean, var],
outputs=[y, output_mean, output_var],
name="test_batchnorm_example_training_mode",
)
# input size: (2, 3, 4, 5)
x = np.random.randn(2, 3, 4, 5).astype(np.float32)
s = np.random.randn(3).astype(np.float32)
bias = np.random.randn(3).astype(np.float32)
mean = np.random.randn(3).astype(np.float32)
var = np.random.rand(3).astype(np.float32)
training_mode = 1
momentum = 0.9
epsilon = 1e-2
y, output_mean, output_var = _batchnorm_training_mode(
x, s, bias, mean, var, momentum, epsilon
)
node = onnx.helper.make_node(
"BatchNormalization",
inputs=["x", "s", "bias", "mean", "var"],
outputs=["y", "output_mean", "output_var"],
epsilon=epsilon,
training_mode=training_mode,
)
# output size: (2, 3, 4, 5)
expect(
node,
inputs=[x, s, bias, mean, var],
outputs=[y, output_mean, output_var],
name="test_batchnorm_epsilon_training_mode",
)