Files
ascend-tools/pt2pb/onnx-tensorflow/test/backend/test_node.py
T
2020-10-14 08:55:07 +08:00

3725 lines
154 KiB
Python

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import math
import unittest
import numpy as np
import tensorflow as tf
from onnx_tf.backend import onnx_graph_to_tensorflow_rep
from onnx_tf.backend import run_node
from onnx_tf.common import supports_device
from onnx_tf.common.legacy import legacy_onnx_pre_ver, legacy_opset_pre_ver
from onnx_tf.common.pooling_helper import py_pool
from onnx import helper
from onnx import TensorProto
from onnx import defs
class TestNode(unittest.TestCase):
""" Tests for nodes
"""
def _get_rnd_float32(self, low=-1.0, high=1.0, shape=None):
output = np.random.uniform(low, high, shape)
if shape is None:
return np.float32(output)
else:
return output.astype(np.float32)
def _get_rnd_int(self, low, high=None, shape=None, dtype=np.int32):
return np.random.randint(low, high, size=shape, dtype=dtype)
def _elu(self, x):
# f(x) = alpha * (exp(x) - 1.) for x < 0,
# f(x) = x for x >= 0
if x < 0.:
return np.expm1(x)
return x
def _leaky_relu(self, x, alpha):
# f(x) = alpha * x for x < 0,
# f(x) = x for x >= 0
if x < 0.:
return alpha * x
return x
def test_abs(self):
node_def = helper.make_node("Abs", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.abs(x))
def test_acosh(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Acosh.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Acosh", ["X"], ["Y"])
x = self._get_rnd_float32(low=1.0, high=np.finfo(np.float32).max, shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.arccosh(x))
def test_add(self):
node_def = helper.make_node("Add", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[5, 10, 5, 5])
y = self._get_rnd_float32(shape=[10, 1, 1])
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"],
np.add(x, y.reshape([1, 10, 1, 1])))
# node_def = helper.make_node("Add", ["A", "B"], ["C"], broadcast=1)
# a = self._get_rnd([10, 10])
# b = self._get_rnd([10, 10])
# output = run_node(node_def, [a, b])
# np.testing.assert_almost_equal(output["C"], np.add(a, b))
# node_def = helper.make_node("Add", ["A", "B"], ["C"], broadcast=1)
# a = self._get_rnd([10, 10])
# b = self._get_rnd([10,])
# output = run_node(node_def, [a, b])
# np.testing.assert_almost_equal(output["C"], np.add(a, b))
def test_arg_max(self):
for axis in [0, 1]:
node_def = helper.make_node("ArgMax", ["data"], ["reduced"],
axis=axis,
keepdims=0)
data = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [data])
np.testing.assert_almost_equal(output["reduced"],
np.argmax(data, axis=axis))
# test select_last_index
if not legacy_opset_pre_ver(12):
# select_last_index = 0
node_def = helper.make_node("ArgMax", ["data"], ["reduced"],
axis=axis,
keepdims=0,
select_last_index=0)
data = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [data])
np.testing.assert_almost_equal(output["reduced"],
np.argmax(data, axis=axis))
# select_last_index = 1
node_def = helper.make_node("ArgMax", ["data"], ["reduced"],
axis=axis,
keepdims=0,
select_last_index=1)
data = np.array([[1, 2, 3, 5, 3, 4, 5, 1], [2, 9, 3, 5, 9, 4, 5, 1]])
output = run_node(node_def, [data])
data = np.flip(data, axis)
result = np.argmax(data, axis=axis)
result = data.shape[axis] - result - 1
np.testing.assert_almost_equal(output["reduced"], result)
def test_arg_min(self):
for axis in [0, 1]:
node_def = helper.make_node("ArgMin", ["data"], ["reduced"],
axis=axis,
keepdims=0)
data = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [data])
np.testing.assert_almost_equal(output["reduced"],
np.argmin(data, axis=axis))
# test select_last_index
if not legacy_opset_pre_ver(12):
# select_last_index = 0
node_def = helper.make_node("ArgMin", ["data"], ["reduced"],
axis=axis,
keepdims=0,
select_last_index=0)
data = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [data])
np.testing.assert_almost_equal(output["reduced"],
np.argmin(data, axis=axis))
# select_last_index = 1
node_def = helper.make_node("ArgMin", ["data"], ["reduced"],
axis=axis,
keepdims=0,
select_last_index=1)
data = np.array([[1, 2, 3, 5, 3, 4, 5, 1], [2, 7, 3, 5, 2, 4, 5, 6]])
output = run_node(node_def, [data])
data = np.flip(data, axis)
result = np.argmin(data, axis=axis)
result = data.shape[axis] - result - 1
np.testing.assert_almost_equal(output["reduced"], result)
def test_asinh(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Asinh.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Asinh", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.arcsinh(x))
def test_atanh(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Atanh.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Atanh", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.arctanh(x))
def _batch_normalization(self, x, mean, variance, bias, scale,
variance_epsilon):
inv = np.reciprocal(np.sqrt(variance + variance_epsilon))
if scale is not None:
inv *= scale
return x * inv + (bias - mean * inv if bias is not None else -mean * inv)
def test_batch_normalization(self):
if legacy_opset_pre_ver(6):
raise unittest.SkipTest("Backend doesn't support consumed flag")
node_def = helper.make_node("BatchNormalization",
["X", "scale", "bias", "mean", "var"], ["Y"],
epsilon=0.001)
x_shape = [3, 5, 4, 2]
param_shape = [5]
_param_shape = [1, 5, 1, 1]
x = self._get_rnd_float32(0, 1, shape=x_shape)
m = self._get_rnd_float32(0, 1, shape=param_shape)
_m = m.reshape(_param_shape)
v = self._get_rnd_float32(0, 1, shape=param_shape)
_v = v.reshape(_param_shape)
scale = self._get_rnd_float32(0, 1, shape=param_shape)
_scale = scale.reshape(_param_shape)
bias = self._get_rnd_float32(0, 1, shape=param_shape)
_bias = bias.reshape(_param_shape)
golden = self._batch_normalization(x, _m, _v, _bias, _scale, 0.001)
output = run_node(node_def, [x, scale, bias, m, v])
np.testing.assert_almost_equal(output["Y"], golden, decimal=5)
def test_cast(self):
if legacy_onnx_pre_ver(1, 2) or legacy_opset_pre_ver(6):
test_cases = [("FLOAT", tf.float32), ("UINT8", tf.uint8),
("INT8", tf.int8),
("UINT16", tf.uint16), ("INT16", tf.int16),
("INT32", tf.int32), ("INT64", tf.int64), ("BOOL", tf.bool),
("FLOAT16", tf.float16), ("DOUBLE", tf.float64),
("COMPLEX64", tf.complex64), ("COMPLEX128", tf.complex128)]
else:
test_cases = [(TensorProto.FLOAT, tf.float32),
(TensorProto.UINT8, tf.uint8), (TensorProto.INT8, tf.int8),
(TensorProto.UINT16, tf.uint16),
(TensorProto.INT16, tf.int16),
(TensorProto.INT32, tf.int32),
(TensorProto.INT64, tf.int64), (TensorProto.BOOL, tf.bool),
(TensorProto.FLOAT16, tf.float16),
(TensorProto.DOUBLE, tf.float64),
(TensorProto.COMPLEX64, tf.complex64),
(TensorProto.COMPLEX128, tf.complex128)]
if not legacy_opset_pre_ver(9):
test_cases.append((TensorProto.STRING, tf.string))
for ty, tf_type in test_cases:
node_def = helper.make_node("Cast", ["input"], ["output"], to=ty)
vector = [2, 3]
output = run_node(node_def, [vector])
np.testing.assert_equal(output["output"].dtype, tf_type)
if not legacy_opset_pre_ver(9):
test_cases2 = [(TensorProto.FLOAT, tf.float32),
(TensorProto.INT32, tf.int32),
(TensorProto.INT64, tf.int64),
(TensorProto.DOUBLE, tf.float64)]
for ty, tf_type in test_cases2:
node_def = helper.make_node("Cast", ["input"], ["output"], to=ty)
vector = ['2', '3']
output = run_node(node_def, [vector])
np.testing.assert_equal(output["output"].dtype, tf_type)
def test_ceil(self):
node_def = helper.make_node("Ceil", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.ceil(x))
def test_compress(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest(
"ONNX version {} doesn't support Compress.".format(
defs.onnx_opset_version()))
axis = 1
node_def = helper.make_node("Compress",
inputs=['X', 'condition'],
outputs=['Y'],
axis=axis)
x = self._get_rnd_float32(shape=[5, 5, 5])
cond = np.array([1, 0, 1])
output = run_node(node_def, inputs=[x, cond])
np.testing.assert_almost_equal(output['Y'], np.compress(cond, x, axis=axis))
def test_concat(self):
shape = [10, 20, 5]
for axis in range(len(shape)):
node_def = helper.make_node("Concat", ["X1", "X2"], ["Y"], axis=axis)
x1 = self._get_rnd_float32(shape=shape)
x2 = self._get_rnd_float32(shape=shape)
output = run_node(node_def, [x1, x2])
np.testing.assert_almost_equal(output["Y"], np.concatenate((x1, x2),
axis))
def test_constant(self):
shape = [16, 16]
values = np.random.randn(*shape).flatten().astype(float)
const2_onnx = helper.make_tensor("const2", TensorProto.DOUBLE, shape,
values)
node_def = helper.make_node("Constant", [], ["Y"], value=const2_onnx)
output = run_node(node_def, [])
np.testing.assert_equal(output["Y"].shape, shape)
np.testing.assert_almost_equal(output["Y"].flatten(), values)
# test sparse tensor
if not legacy_opset_pre_ver(11):
expected = np.array([[1, 0, 0, 0], [0, 0, 2, 0], [0, 0, 0, 0]])
x = np.array([[0, 0], [1, 2]]).flatten().astype(np.int64)
values = helper.make_tensor("values", TensorProto.INT32, [2], [1, 2])
indices = helper.make_tensor("indices", TensorProto.INT64, [2, 2], x)
a = helper.make_sparse_tensor(values, indices, [3, 4])
node_def = helper.make_node("Constant", [], ["Y"], sparse_value=a)
output = run_node(node_def, [])
b = tf.sparse_to_dense(output["Y"].indices, output["Y"].dense_shape,
output["Y"].values)
result = b.eval(session=tf.Session())
np.testing.assert_equal(result, expected)
if not legacy_opset_pre_ver(12):
float_attr = 1.0
floats_attr = [1.0, 2.0, 3.0]
int_attr = np.int64(123)
ints_attr = [np.int64(4), np.int64(5), np.int64(6)]
string_attr = 'The Cat in the Hat'
strings_attr = [
'Green Eggs and Ham', 'How the Grinch Stole Christmas!',
'The Cat in the Hat Comes Back'
]
testcases = [(helper.make_node("Constant", [], ["Y"],
value_float=float_attr), float_attr),
(helper.make_node("Constant", [], ["Y"],
value_floats=floats_attr), floats_attr),
(helper.make_node("Constant", [], ["Y"],
value_int=int_attr), int_attr),
(helper.make_node("Constant", [], ["Y"],
value_ints=ints_attr), ints_attr),
(helper.make_node("Constant", [], ["Y"],
value_string=string_attr), string_attr),
(helper.make_node("Constant", [], ["Y"],
value_strings=strings_attr), strings_attr)]
for node_def, expected in testcases:
output = run_node(node_def, [])
if isinstance(expected, str):
np.testing.assert_string_equal(output["Y"].decode('UTF-8'), expected)
elif isinstance(expected, list) and isinstance(expected[0], str):
for i in range(len(expected)):
np.testing.assert_string_equal(output['Y'][i].decode('UTF-8'),
expected[i])
else:
np.testing.assert_equal(output["Y"], expected)
def test_constant_fill(self):
if not legacy_opset_pre_ver(9):
raise unittest.SkipTest(
"ONNX version {} doesn't support ConstantFill.".format(
defs.onnx_opset_version()))
shape = [1, 2, 3, 4]
extra_shape = [5, 6]
value = 3.
node_def = helper.make_node(
"ConstantFill",
["X"],
["Y"],
value=value,
extra_shape=extra_shape,
dtype=1,
)
x = self._get_rnd_float32(shape=shape)
y = np.zeros(shape + extra_shape)
y.fill(value)
output = run_node(node_def, [x])
np.testing.assert_equal(output["Y"].dtype, tf.float32)
np.testing.assert_equal(output["Y"], y)
def test_constant_of_shape(self):
if defs.onnx_opset_version() < 9:
raise unittest.SkipTest(
"ONNX version {} doesn't support ConstantOfShape.".format(
defs.onnx_opset_version()))
v = helper.make_tensor("value", TensorProto.FLOAT, [1], [1])
node_def = helper.make_node("ConstantOfShape", ["X"], ["Y"], value=v)
x = np.array([4, 3, 2])
output = run_node(node_def, inputs=[x])
np.testing.assert_almost_equal(output["Y"], np.ones(x, dtype=np.float32))
v = helper.make_tensor("value", TensorProto.INT32, [1], [0])
node_def = helper.make_node("ConstantOfShape", ["X"], ["Y"], value=v)
x = np.array([10, 6])
output = run_node(node_def, inputs=[x])
np.testing.assert_almost_equal(output["Y"], np.zeros(x, dtype=np.int32))
def test_conv(self):
device = "CUDA" if supports_device("CUDA") else "CPU"
N, C, H, W = 4, 3, 5, 5
x_shape = [N, C, H, W]
K, kH, kW = 6, 3, 3
weight_shape = [K, C, kH, kW]
node_def = helper.make_node("Conv", ["X", "weights"], ["Y"],
pads=[1, 1, 1, 1],
kernel_shape=[kH, kW])
x = self._get_rnd_float32(shape=x_shape)
weights = self._get_rnd_float32(shape=weight_shape)
output = run_node(node_def, [x, weights], device=device)
out_shape = [N, K, H, W]
test_output = np.zeros(out_shape)
for n in range(N):
for c in range(C):
for h in range(H):
for w in range(W):
for k in range(K):
for kh in range(kH):
for kw in range(kW):
h_in_range = (h - kH // 2 + kh) < H and (h - kH // 2 +
kh) >= 0
w_in_range = (w - kW // 2 + kw) < W and (w - kW // 2 +
kw) >= 0
if h_in_range and w_in_range:
test_output[n][k][h][w] += (
x[n][c][h - kH // 2 + kh][w - kW // 2 + kw] *
weights[k][c][kh][kw])
np.testing.assert_almost_equal(output["Y"], test_output, decimal=5)
def test_conv_integer(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support ConvInteger.".format(
defs.onnx_opset_version()))
# Test w_zero_point
x = np.array([2, 3, 4, 5, 6, 7, 8, 9, 10]).astype(np.int8).reshape(
(1, 1, 3, 3))
w = np.array([2, 2, 2, 2]).astype(np.int8).reshape((1, 1, 2, 2))
w_zero_point = np.int8(1)
y = np.array([16, 20, 28, 32]).astype(np.int32).reshape((1, 1, 2, 2))
node = helper.make_node("ConvInteger",
["X", "W", "x_zero_point", "w_zero_point"], ["Y"],
kernel_shape=[2, 2],
pads=[0, 0, 0, 0],
dilations=[1, 1])
output = run_node(node, [x, w, np.int8(0), w_zero_point])
np.testing.assert_almost_equal(output["Y"], y)
# Test x_zero_point and w_zero_point
x = np.array([2, 3, 4, 5, 6, 7, 8, 9, 10]).astype(np.int8).reshape(
(1, 1, 3, 3))
x_zero_point = np.int8(1)
w = np.array([2, 2, 2, 2]).astype(np.int8).reshape((1, 1, 2, 2))
w_zero_point = np.int8(1)
y = np.array([12, 16, 24, 28]).astype(np.int32).reshape((1, 1, 2, 2))
node = helper.make_node("ConvInteger",
["X", "W", "x_zero_point", "w_zero_point"], ["Y"],
kernel_shape=[2, 2],
pads=[0, 0, 0, 0],
dilations=[1, 1])
output = run_node(node, [x, w, x_zero_point, w_zero_point])
np.testing.assert_almost_equal(output["Y"], y)
# Test w_zero_point as 1d tensor
x = np.array([2, 3, 4, 5, 6, 7, 8, 9, 10]).astype(np.int8).reshape(
(1, 1, 3, 3))
w = np.array([2, 2, 2, 2]).astype(np.int8).reshape((1, 1, 2, 2))
w_zero_point = np.array([1]).astype(np.int8)
y = np.array([16, 20, 28, 32]).astype(np.int32).reshape((1, 1, 2, 2))
node = helper.make_node("ConvInteger",
["X", "W", "x_zero_point", "w_zero_point"], ["Y"],
kernel_shape=[2, 2],
pads=[0, 0, 0, 0],
dilations=[1, 1])
output = run_node(node, [x, w, np.int8(0), w_zero_point])
np.testing.assert_almost_equal(output["Y"], y)
# Test w_zero_point as 1d tensor shape 2
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]).astype(np.int8).reshape(
(1, 1, 3, 3))
w = np.array([2, 2, 2, 2, 2, 2, 2, 2]).astype(np.int8).reshape((2, 1, 2, 2))
w_zero_point = np.array([1, 2]).astype(np.int8)
y = np.array([12, 16, 24, 28, 0, 0, 0, 0]).astype(np.int32).reshape(
(1, 2, 2, 2))
node = helper.make_node("ConvInteger",
["X", "W", "x_zero_point", "w_zero_point"], ["Y"],
kernel_shape=[2, 2],
pads=[0, 0, 0, 0],
dilations=[1, 1])
output = run_node(node, [x, w, np.int8(0), w_zero_point])
np.testing.assert_almost_equal(output["Y"], y)
def test_conv_transpose(self):
device = "CUDA" if supports_device("CUDA") else "CPU"
pads = [1, 1]
node_def = helper.make_node("ConvTranspose", ["X", "weights"], ["Y"],
pads=pads)
x_shape = [1, 3, 4]
x = self._get_rnd_float32(shape=x_shape)
weight_shape = [3, 5, 2]
weights = self._get_rnd_float32(shape=weight_shape)
output = run_node(node_def, [x, weights], device=device)
padh_left = weight_shape[2]-1-pads[0]
padh_right = weight_shape[2]-1-pads[1]
kh = weight_shape[2]
outh = x_shape[2] + padh_right + padh_right - (kh - 1)
out_shape = [x_shape[0], weight_shape[1], outh]
test_output = np.zeros(out_shape)
for b in range(0, x_shape[0]):
for m in range(0, weight_shape[1]):
for c in range(0, x_shape[1]):
for h in range(0, outh):
for k in range(h , h + kh):
if (k - padh_left >= 0):
test_output[b][m][h] += x[b][c][k-padh_left] * weights[c][m][kh+h-1-k]
np.testing.assert_almost_equal(output["Y"], test_output, decimal=5)
# test for spatial dimension of colnolution is 2
pads = [1, 1, 1, 1]
node_def = helper.make_node("ConvTranspose", ["X", "weights"], ["Y"],
pads=pads)
x_shape = [1, 3, 4, 6]
x = self._get_rnd_float32(shape=x_shape)
weight_shape = [3, 5, 2, 2]
weights = self._get_rnd_float32(shape=weight_shape)
output = run_node(node_def, [x, weights],device=device)
padh_left = weight_shape[2]-1-pads[0]
padh_right = weight_shape[2]-1-pads[1]
padw_left = weight_shape[3]-1-pads[2]
padw_right = weight_shape[3]-1-pads[3]
kh = weight_shape[2]
kw = weight_shape[3]
outh = x_shape[2] + padh_right + padh_right - (kh - 1)
outw = x_shape[3] + padw_right + padw_right - (kw - 1)
out_shape = [x_shape[0], weight_shape[1], outh, outw]
test_output = np.zeros(out_shape)
for b in range(0, x_shape[0]):
for m in range(0, weight_shape[1]):
for c in range(0, x_shape[1]):
for h in range(0, outh):
for w in range(0, outw):
for k1 in range(h , h + kh):
for k2 in range(w , w + kw):
if (k1 - padh_left >= 0 and k2 - padw_left >= 0):
test_output[b][m][h][w] += x[b][c][k1-padh_left][k2-padw_left] * weights[c][m][kh+h-1-k1][kw+w-1-k2]
np.testing.assert_almost_equal(output["Y"], test_output, decimal=5)
def test_cosh(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Cosh.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Cosh", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.cosh(x))
def test_cumsum(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest("ONNX version {} doesn't support CumSum.".format(
defs.onnx_opset_version()))
x = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.int32)
axis = 0
node_def = helper.make_node("CumSum", ["x", "axis"], ["y"])
# note: if axis is not provided, np.cumsum() will compute over flattened array,
# which is different than the TensorFlow behavior
y = np.cumsum(x, axis).astype(np.int32)
output = run_node(node_def, [x, axis])
np.testing.assert_almost_equal(output["y"], y)
def test_depth_to_space(self):
node_def = helper.make_node("DepthToSpace", ["X"], ["Y"], blocksize=2)
x_shape = [1, 12, 1, 1]
x = self._get_rnd_float32(shape=x_shape)
output = run_node(node_def, [x])
x = np.transpose(x, (0, 2, 3, 1))
y = np.reshape(np.swapaxes(x.reshape(1, 1, 1, 2, 2, 3), 2, 3), (1, 2, 2, 3))
y = np.transpose(y, (0, 3, 1, 2))
np.testing.assert_almost_equal(output["Y"], y, decimal=5)
def test_dequantize_linear(self):
node_def = helper.make_node("DequantizeLinear",
["x", "x_scale", "x_zero_point"], ["y"])
for x, x_zero_point in [[
self._get_rnd_int(-128, 127, [2, 6], np.int8),
self._get_rnd_int(-128, 127, dtype=np.int8)
],
[
self._get_rnd_int(0, 255, [2, 6], np.uint8),
self._get_rnd_int(0, 255, dtype=np.uint8)
],
[self._get_rnd_int(-512, 512, [2, 6]),
np.int32(0)]]:
x_scale = self._get_rnd_float32(-10., 10)
y = np.subtract(np.float32(x), np.float32(x_zero_point))
y = np.multiply(y, x_scale)
output = run_node(node_def, [x, x_scale, x_zero_point])
np.testing.assert_almost_equal(output["y"], y)
def test_div(self):
node_def = helper.make_node("Div", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[10, 10])
y = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.divide(x, y))
def test_dropout(self):
# Since current ONNX only support inference and
# dropout at inference mode is a no-op,
# therefore dropout is always a no-op operator
# in ONNX.
node_def = helper.make_node("Dropout", ["X"], ["Y"])
if legacy_opset_pre_ver(7):
# at inference mode, is_test is always set to 1
node_def = helper.make_node("Dropout", ["X"], ["Y"], is_test=1)
x = self._get_rnd_float32(shape=[3, 4, 5])
y = x
output = run_node(node_def, [x])
np.testing.assert_equal(output["Y"], y)
def test_dot(self):
# this op is removed
# remove this test in the future
return
node_def = helper.make_node("Dot", ["X", "Y"], ["Z"])
x = np.floor(self._get_rnd_float32(shape=[10, 10]))
y = np.floor(self._get_rnd_float32(shape=[10, 10]))
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.dot(x, y))
def test_dynamic_quantize_linear(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest(
"ONNX version {} doesn't support DynamicQuantizeLinear.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("DynamicQuantizeLinear", ["X"],
["Y", "Y_Scale", "Y_Zero_Point"])
x = self._get_rnd_float32(shape=[3, 4])
min_x = np.minimum(0, np.min(x))
max_x = np.maximum(0, np.max(x))
y_scale = np.float32((max_x - min_x) / (255 - 0)) # uint8 -> [0, 255]
y_zero_point = np.clip(round((0 - min_x) / y_scale), 0,
255).astype(np.uint8)
y = np.clip(np.round(x / y_scale) + y_zero_point, 0, 255).astype(np.uint8)
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], y)
np.testing.assert_almost_equal(output["Y_Scale"], y_scale)
np.testing.assert_almost_equal(output["Y_Zero_Point"], y_zero_point)
def test_elu(self):
node_def = helper.make_node("Elu", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[100])
output = run_node(node_def, [x])
test_output = [self._elu(a) for a in x]
np.testing.assert_almost_equal(output["Y"], test_output)
def test_equal(self):
node_def = helper.make_node("Equal", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[5, 3, 3, 2])
y = self._get_rnd_float32(shape=[3, 3, 1])
output = run_node(node_def, [x, y])
np.testing.assert_equal(output["Z"], np.equal(x,
np.reshape(y, [1, 3, 3, 1])))
def test_erf(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Erf.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Erf", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
exp_output = np.vectorize(math.erf)(x).astype(np.float32)
np.testing.assert_allclose(output['Y'], exp_output, rtol=1e-6, atol=1e-6)
def test_exp(self):
node_def = helper.make_node("Exp", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[100])
x = x - 3.6
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.exp(x))
def test_expand(self):
node_def = helper.make_node("Expand", ["X", "shape"], ["Y"])
x = [[True], [False], [True]]
shape = [2, 1, 6]
y = x * np.ones(shape, dtype=np.bool)
output = run_node(node_def, [x, shape])
np.testing.assert_almost_equal(output["Y"], y)
def test_eye_like(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support EyeLike.".format(
defs.onnx_opset_version()))
for shape in [[6, 10], [10, 6]]:
for off_diagonal_offset in [-10, -6, -3, 0, 3, 6, 7, 10]:
node_def = helper.make_node("EyeLike", ['x'], ['y'],
dtype=1,
k=off_diagonal_offset)
x = self._get_rnd_int(0, 100, shape=shape)
y = np.eye(shape[0], shape[1], k=off_diagonal_offset, dtype=np.float32)
output = run_node(node_def, [x])
np.testing.assert_equal(output['y'], y)
def test_flatten(self):
shape = [10, 2, 3, 4, 5]
x = self._get_rnd_float32(shape=shape)
for axis in range(-len(shape), len(shape)):
node_def = helper.make_node("Flatten", ["X"], ["Y"], axis=axis)
output = run_node(node_def, [x])
if axis == 0:
new_shape = (1, -1)
else:
new_shape = (np.prod(shape[0:axis]).astype(int), -1)
np.testing.assert_almost_equal(output["Y"], np.reshape(x, new_shape))
def test_gather(self):
node_def = helper.make_node("Gather", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[10, 10])
y = [[0, 1], [1, 2]]
output = run_node(node_def, [x, y])
test_output = np.zeros((2, 2, 10))
for i in range(0, 2):
for j in range(0, 10):
test_output[0][i][j] = x[i][j]
for i in range(0, 2):
for j in range(0, 10):
test_output[1][i][j] = x[i + 1][j]
np.testing.assert_almost_equal(output["Z"], test_output)
if defs.onnx_opset_version() >= 11:
# test negative indices
y = [[-10, -9], [1, -8]]
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], test_output)
# test out of bound indices
for y in ([[-10, 11], [1, -8]], [[-10, -11], [1, -8]]):
try:
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], test_output)
raise AssertionError("Expected ValueError not raised for indices %d" %
str(y))
except tf.errors.InvalidArgumentError as e:
assert 'Gather indices are out of bound' in str(e), str(y)
# test non-0 and negative axis
axis = -3
node_def = helper.make_node("Gather", ["X", "Y"], ["Z"], axis=axis)
x = np.reshape(np.arange(5 * 4 * 3 * 2), (5, 4, 3, 2))
y = np.array([0, 1, 3])
test_output = np.take(x, y, axis=axis)
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], test_output)
# test axis attribute validation
for axis in [-5, 4, 10]:
try:
node_def = helper.make_node("Gather", ["X", "Y"], ["Z"], axis=axis)
run_node(node_def, [x, y])
raise AssertionError(
"Expected ValueError not raised for axis value %d" % axis)
except ValueError as e:
assert 'out of bounds' in str(e), str(e) + ' for axis ' + str(axis)
def test_gather_elements(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest(
"ONNX version {} doesn't support GatherElements.".format(
defs.onnx_opset_version()))
data_dtype = np.int32
data = np.array([
[[10, 11], [12, 13], [14, 15], [16, 17], [18, 19]],
[[20, 21], [22, 23], [24, 25], [26, 27], [28, 29]],
[[30, 31], [32, 33], [34, 35], [36, 37], [38, 39]],
[[40, 41], [42, 43], [44, 45], [46, 47], [48, 49]],
],
dtype=data_dtype)
# test default axis
indices = np.array([[[3, 0], [2, 0], [1, 0], [0, 0], [3, 1]]],
dtype=np.int64)
ref_output = np.array([[[40, 11], [32, 13], [24, 15], [16, 17], [48, 29]]],
dtype=data_dtype)
node_def = helper.make_node("GatherElements", ["data", "indices"],
["outputs"])
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# test non-default axis
indices = np.array([[[3, 0], [2, 1], [1, 2], [0, 3]]], dtype=data_dtype)
ref_output = np.array([
[[16, 11], [14, 13], [12, 15], [10, 17]],
],
dtype=data_dtype)
node_def = helper.make_node("GatherElements", ["data", "indices"],
["outputs"],
axis=1)
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# test negative axis
indices = np.array([
[[1, 1, -2], [1, -2, 1], [-1, 1, -1], [-2, 1, -2], [-2, 1, 1]],
],
dtype=data_dtype)
ref_output = np.array([
[[11, 11, 10], [13, 12, 13], [15, 15, 15], [16, 17, 16], [18, 19, 19]],
],
dtype=data_dtype)
node_def = helper.make_node("GatherElements", ["data", "indices"],
["outputs"],
axis=2)
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
def test_gather_nd(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest(
"ONNX version {} doesn't support GatherND.".format(
defs.onnx_opset_version()))
# valid positive and negative indices for elements
data = np.array([[0, 1], [2, 3]], dtype=np.int64)
indices = np.array([[0, 0], [1, 1], [-1, -2]], dtype=np.int64)
ref_output = np.array([0, 3, 2], dtype=np.int64)
node_def = helper.make_node("GatherND", ["data", "indices"], ["outputs"])
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# valid positive and negative indices for slices
data = np.arange(16, dtype=np.int32).reshape([2, 2, 4])
indices = np.array([[0, 0], [-1, -2]], dtype=np.int64)
ref_output = np.array([[0, 1, 2, 3], [8, 9, 10, 11]], dtype=np.int32)
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
indices = np.array([[[0, 0]], [[-1, 0]]], dtype=np.int64)
ref_output = np.array([[[0, 1, 2, 3]], [[8, 9, 10, 11]]], dtype=np.int32)
output = run_node(node_def, [data, indices])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# indices out of bounds
indices = np.array([[5, 0], [-1, -3]], dtype=np.int64)
with np.testing.assert_raises(tf.errors.InvalidArgumentError):
output = run_node(node_def, [data, indices])
indices = np.array([[1, 1, 6], [-2, -1, -9]], dtype=np.int32)
with np.testing.assert_raises(tf.errors.InvalidArgumentError):
output = run_node(node_def, [data, indices])
def test_gemm(self):
# Compute Y = alpha * A * B + beta * C
node_def = helper.make_node("Gemm", ["A", "B", "C"], ["Y"],
transA=0,
transB=0,
alpha=1.0,
beta=1.0)
x = np.floor(self._get_rnd_float32(shape=[10, 10]))
y = np.floor(self._get_rnd_float32(shape=[10, 10]))
z = np.floor(self._get_rnd_float32(shape=[10, 10]))
output = run_node(node_def, [x, y, z])
test_output = np.matmul(x, y) + z
np.testing.assert_almost_equal(output["Y"], test_output)
def test_global_average_pool(self):
# Image case: (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 the width of the data
#
# Non-image case: (N x C x D1 x D2 ... Dn)
#
# Output data tensor from pooling across the input tensor.
# Dimensions will be N x C x 1 x 1
node_def = helper.make_node("GlobalAveragePool", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[10, 10, 2, 3])
output = run_node(node_def, [x])
test_output = np.zeros([10, 10, 1, 1])
for i1 in range(0, 10):
for i2 in range(0, 10):
sum = 0
for j1 in range(0, 2):
for j2 in range(0, 3):
sum += x[i1][i2][j1][j2]
test_output[i1][i2][0][0] = sum / 6.
np.testing.assert_almost_equal(output["Y"], test_output)
def test_hardmax(self):
shape = [2, 3, 4, 5]
x = self._get_rnd_float32(shape=shape)
for axis in range(-len(shape), len(shape)):
node_def = helper.make_node("Hardmax", ["X"], ["Y"], axis=axis)
output = run_node(node_def, [x])
shape_in_2d = (np.prod(shape[0:axis]).astype(int),
np.prod(shape[axis:len(shape)]))
x_in_2d = np.reshape(x, shape_in_2d)
y = np.eye(x_in_2d.shape[1], dtype=x.dtype)[np.argmax(x_in_2d, axis=1)]
np.testing.assert_almost_equal(output["Y"], np.reshape(y, shape))
def test_if(self):
true_val = helper.make_tensor(name='true_tensor',
data_type=TensorProto.INT64,
dims=(),
vals=[np.int64(1)])
false_val = helper.make_tensor(name='false_tensor',
data_type=TensorProto.INT64,
dims=(),
vals=[np.int64(0)])
true_node = helper.make_node('Constant',
inputs=[],
outputs=['true'],
value=true_val)
false_node = helper.make_node('Constant',
inputs=[],
outputs=['false'],
value=false_val)
true_out = helper.make_tensor_value_info('true', TensorProto.INT64, [])
false_out = helper.make_tensor_value_info('false', TensorProto.INT64, [])
true_graph = helper.make_graph(nodes=[true_node],
name="true_graph",
inputs=[],
outputs=[true_out])
false_graph = helper.make_graph(nodes=[false_node],
name="false_graph",
inputs=[],
outputs=[false_out])
node_def = helper.make_node('If', ['cond'], ['outputs'],
then_branch=true_graph,
else_branch=false_graph)
for cond, exp in [[True, true_val], [False, false_val]]:
output = run_node(node_def, [cond])
np.testing.assert_equal(output['outputs'], exp.int64_data)
x = self._get_rnd_int(low=-50, high=50, dtype=np.int64)
y = self._get_rnd_int(low=-50, high=50, dtype=np.int64)
z = self._get_rnd_int(low=-50, high=50, dtype=np.int64)
x_val = helper.make_tensor(name='x_tensor',
data_type=TensorProto.INT64,
dims=(),
vals=[x])
y_val = helper.make_tensor(name='y_tensor',
data_type=TensorProto.INT64,
dims=(),
vals=[y])
z_val = helper.make_tensor(name='z_tensor',
data_type=TensorProto.INT64,
dims=(),
vals=[z])
x_node = helper.make_node('Constant', inputs=[], outputs=['x'], value=x_val)
y_node = helper.make_node('Constant', inputs=[], outputs=['y'], value=y_val)
z_node = helper.make_node('Constant', inputs=[], outputs=['z'], value=z_val)
add_node = helper.make_node('Add', inputs=['x', 'y'], outputs=['sum'])
sub_node = helper.make_node('Sub', inputs=['x', 'y'], outputs=['diff'])
mul1_node = helper.make_node('Mul', inputs=['sum', 'z'], outputs=['prod1'])
mul2_node = helper.make_node('Mul', inputs=['diff', 'z'], outputs=['prod2'])
x_out = helper.make_tensor_value_info('x', TensorProto.INT64, [])
y_out = helper.make_tensor_value_info('y', TensorProto.INT64, [])
z_out = helper.make_tensor_value_info('z', TensorProto.INT64, [])
sum_out = helper.make_tensor_value_info('sum', TensorProto.INT64, [])
diff_out = helper.make_tensor_value_info('diff', TensorProto.INT64, [])
prod1_out = helper.make_tensor_value_info('prod1', TensorProto.INT64, [])
prod2_out = helper.make_tensor_value_info('prod2', TensorProto.INT64, [])
true_graph = helper.make_graph(nodes=[add_node, mul1_node],
name="true_graph",
inputs=[x_out, y_out, z_out],
outputs=[sum_out, prod1_out])
false_graph = helper.make_graph(nodes=[sub_node, mul2_node],
name="false_graph",
inputs=[x_out, y_out, z_out],
outputs=[diff_out, prod2_out])
less_node = helper.make_node('Less', inputs=['x', 'y'], outputs=['cond'])
if_node = helper.make_node('If',
inputs=['cond'],
outputs=['result'],
then_branch=true_graph,
else_branch=false_graph)
result_out = helper.make_tensor_value_info('result', TensorProto.INT64, [])
graph = helper.make_graph(
nodes=[x_node, y_node, z_node, less_node, if_node],
name="test_if",
inputs=[],
outputs=[result_out])
tf_rep = onnx_graph_to_tensorflow_rep(graph)
output = tf_rep.run({})
expected = [x + y, (x + y) * z] if x < y else [x - y, (x - y) * z]
np.testing.assert_equal(output['result'], expected)
def test_image_sacler(self):
# Input: (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 the width of the data
# Scale: (flout, default 1.0) the scale to apply
# Bias: applied to each channel, same size as C
# Output has same shape and type as input
x = self._get_rnd_float32(shape=[1, 3, 224, 224])
#random distribution over [0,1), so add 0.1
scale = np.random.rand(1)[0] + 0.1
bias = np.random.rand(3)
node_def = helper.make_node("ImageScaler", ["X"], ["Y"],
scale=scale,
bias=bias)
output = run_node(node_def, [x])
test_out = np.multiply(x, scale)
test_out = np.transpose(test_out, [0, 2, 3, 1])
test_out = np.add(test_out, bias)
test_out = np.transpose(test_out, [0, 3, 1, 2])
np.testing.assert_almost_equal(output["Y"], test_out)
def test_is_inf(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest("ONNX version {} doesn't support IsInf.".format(
defs.onnx_opset_version()))
input = np.array([-1.2, np.nan, np.inf, 2.8, np.NINF, np.inf],
dtype=np.float32)
expected_output = {
"node_def": np.isinf(input),
"node_def_neg_false": np.isposinf(input),
"node_def_pos_false": np.isneginf(input)
}
node_defs = {
"node_def":
helper.make_node("IsInf", ["X"], ["Y"]),
"node_def_neg_false":
helper.make_node("IsInf", ["X"], ["Y"], detect_negative=0),
"node_def_pos_false":
helper.make_node("IsInf", ["X"], ["Y"], detect_positive=0)
}
for key in node_defs:
output = run_node(node_defs[key], [input])
np.testing.assert_equal(output["Y"], expected_output[key])
def test_isnan(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support IsNaN.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("IsNaN", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 3])
x[0][1] = x[1][0] = x[2][2] = np.nan
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.isnan(x))
def test_global_lp_pool(self):
# Image case: (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 the width of the data
#
# Non-image case: (N x C x D1 x D2 ... Dn)
#
# Output data tensor from pooling across the input tensor.
# Dimensions will be N x C x 1 x 1
node_def = helper.make_node("GlobalLpPool", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[10, 10, 2, 3])
output = run_node(node_def, [x])
test_output = np.zeros([10, 10, 1, 1])
for i1 in range(0, 10):
for i2 in range(0, 10):
tmp = np.zeros([2, 3])
for j1 in range(0, 2):
for j2 in range(0, 3):
tmp[j1][j2] = x[i1][i2][j1][j2]
test_output[i1][i2][0][0] = np.linalg.norm(tmp)
np.testing.assert_almost_equal(output["Y"], test_output, decimal=5)
def test_global_max_pool(self):
# Image case: (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 the width of the data
#
# Non-image case: (N x C x D1 x D2 ... Dn)
#
# Output data tensor from pooling across the input tensor.
# Dimensions will be N x C x 1 x 1
node_def = helper.make_node("GlobalMaxPool", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[10, 10, 2, 3])
output = run_node(node_def, [x])
test_output = np.zeros([10, 10, 1, 1])
for i1 in range(0, 10):
for i2 in range(0, 10):
max = x[i1][i2][0][0]
for j1 in range(0, 2):
for j2 in range(0, 3):
if max < x[i1][i2][j1][j2]:
max = x[i1][i2][j1][j2]
test_output[i1][i2][0][0] = max
np.testing.assert_almost_equal(output["Y"], test_output)
def test_less(self):
node_def = helper.make_node("Less", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[5, 3, 3, 2])
y = self._get_rnd_float32(shape=[3, 3, 1])
output = run_node(node_def, [x, y])
np.testing.assert_equal(output["Z"], np.less(x, np.reshape(y,
[1, 3, 3, 1])))
def test_lp_normalization(self):
for ordr in range(1, 3):
node_def = helper.make_node("LpNormalization", ["X"], ["Y"], p=ordr)
x = self._get_rnd_float32(shape=[2, 2, 3, 2])
output = run_node(node_def, [x])
np.testing.assert_allclose(
output["Y"],
x / np.expand_dims(np.linalg.norm(x, axis=-1, ord=ordr), -1),
rtol=1e-3)
def test_l_r_n(self):
# Each input value is divided by:
#
# (bias+(alpha/size)*sum(xi^2 for every xi in the local region))^beta
alpha = 2.0
beta = 1.0
bias = 5.0
size = 3
node_def = helper.make_node("LRN", ["X"], ["Y"],
alpha=alpha,
beta=beta,
bias=bias,
size=size)
x = self._get_rnd_float32(shape=[10, 2, 10, 10])
output = run_node(node_def, [x])
test_output = np.zeros([10, 10, 10, 2])
x = np.transpose(x, axes=[0, 2, 3, 1])
for i1 in range(0, 10):
for i2 in range(0, 10):
for j1 in range(0, 10):
for j2 in range(0, 2):
sqr_sum = 0.
# size of 3 means radius 1 in TF speak
# i.e. the immediate neighbouring values
# if "previous" neighbour exists
if j2 > 0:
sqr_sum += x[i1][i2][j1][j2 - 1] * x[i1][i2][j1][j2 - 1]
# current value
sqr_sum += x[i1][i2][j1][j2] * x[i1][i2][j1][j2]
# if "next" neighbour exists
if j2 < 2 - 1:
sqr_sum += x[i1][i2][j1][j2 + 1] * x[i1][i2][j1][j2 + 1]
test_output[i1][i2][j1][j2] = \
x[i1][i2][j1][j2] / ((bias + (alpha * 1. / size) * sqr_sum) ** beta)
test_output = np.transpose(test_output, axes=[0, 3, 1, 2])
np.testing.assert_almost_equal(output["Y"], test_output)
def test_floor(self):
node_def = helper.make_node("Floor", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[100])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.floor(x))
def test_leakyrelu(self):
node_def = helper.make_node("LeakyRelu", ["X"], ["Y"], alpha=0.8)
x = np.floor(self._get_rnd_float32(shape=[100]))
output = run_node(node_def, [x])
test_output = [self._leaky_relu(a, 0.8) for a in x]
np.testing.assert_almost_equal(output["Y"], test_output)
def test_log(self):
node_def = helper.make_node("Log", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[100])
x = x + 3.6
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.log(x))
def test_loop(self):
add1_node = helper.make_node('Add', inputs=['x', 'x'], outputs=['sum1'])
neg_node = helper.make_node('Neg', inputs=['sum1'], outputs=['neg_sum1'])
add2_node = helper.make_node('Add',
inputs=['y', 'neg_sum1'],
outputs=['sum2'])
add3_node = helper.make_node('Add',
inputs=['sum1', 'sum2'],
outputs=['sum3'])
less_node = helper.make_node('Less',
inputs=['sum1', 'sum2'],
outputs=['new_cond'])
greater_node = helper.make_node('Greater',
inputs=['sum1', 'sum2'],
outputs=['new_cond'])
m_in = helper.make_tensor_value_info('M', TensorProto.INT64, [])
cond_in = helper.make_tensor_value_info('cond', TensorProto.BOOL, [])
cond_int_in = helper.make_tensor_value_info('cond', TensorProto.INT32, [])
x_in = helper.make_tensor_value_info('x', TensorProto.INT32, [None])
y_in = helper.make_tensor_value_info('y', TensorProto.INT32, [None])
cond_out = helper.make_tensor_value_info('cond', TensorProto.BOOL, [])
new_cond_out = helper.make_tensor_value_info('new_cond', TensorProto.BOOL,
[])
sum1_out = helper.make_tensor_value_info('sum1', TensorProto.INT32, [None])
sum2_out = helper.make_tensor_value_info('sum2', TensorProto.INT32, [None])
sum3_out = helper.make_tensor_value_info('sum3', TensorProto.INT32, [None])
v1_initial = np.array([1, 1], dtype=np.int32)
v2_initial = np.array([100, 100], dtype=np.int32)
# test for loop
M = np.int64(10)
cond = True # value will be ignore because optional "cond" input will be skip
graph = helper.make_graph(nodes=[add1_node, neg_node, add2_node, add3_node],
name="for_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop', ['M', '', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([1024, 1024], dtype=np.int32),
np.array([-1946, -1946], dtype=np.int32)
]
scan_outputs = [
np.array([[100, 100], [98, 98], [94, 94], [86, 86], [70, 70], [38, 38],
[-26, -26], [-154, -154], [-410, -410], [-922, -922]],
dtype=np.int32)
]
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test while loop
M = 0 # value will be ignore because optional "M" input will be skip
cond = v1_initial < v2_initial
graph = helper.make_graph(
nodes=[add1_node, neg_node, add2_node, add3_node, less_node],
name="while_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[new_cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop',
['', 'cond', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([64, 64], dtype=np.int32),
np.array([-26, -26], dtype=np.int32)
]
scan_outputs = [
np.array([[100, 100], [98, 98], [94, 94], [86, 86], [70, 70], [38, 38]],
dtype=np.int32)
]
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test do-while loop
M = 0 # value will be ignore because optional "M" input will be skip
cond = 1
graph = helper.make_graph(
nodes=[add1_node, neg_node, add2_node, add3_node, greater_node],
name="do_while_loop_graph",
inputs=[m_in, cond_int_in, x_in, y_in],
outputs=[new_cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop',
['', 'cond', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([2, 2], dtype=np.int32),
np.array([98, 98], dtype=np.int32)
]
scan_outputs = [np.array([[100, 100]], dtype=np.int32)]
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test for loop and while loop conbine
M = np.int64(4)
cond = v1_initial < v2_initial
graph = helper.make_graph(
nodes=[add1_node, neg_node, add2_node, add3_node, less_node],
name="for_and_while_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[new_cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop',
['M', 'cond', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([16, 16], dtype=np.int32),
np.array([70, 70], dtype=np.int32)
]
scan_outputs = [
np.array([[100, 100], [98, 98], [94, 94], [86, 86]], dtype=np.int32)
]
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test for loop that doesn't run at all (M = 0)
M = np.int64(0)
cond = True # value will be ignore because optional "cond" input will be skip
graph = helper.make_graph(nodes=[add1_node, neg_node, add2_node, add3_node],
name="for_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop', ['M', '', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([1, 1], dtype=np.int32),
np.array([100, 100], dtype=np.int32)
]
scan_outputs = np.array([], dtype=np.int32).reshape(1, 0, 2)
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test while loop that doesn't run at all (cond = False)
M = 0 # value will be ignore because optional "M" input will be skip
cond = False
graph = helper.make_graph(
nodes=[add1_node, neg_node, add2_node, add3_node, less_node],
name="while_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[new_cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop',
['', 'cond', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([1, 1], dtype=np.int32),
np.array([100, 100], dtype=np.int32)
]
scan_outputs = np.array([], dtype=np.int32).reshape(1, 0, 2)
np.testing.assert_almost_equal(output['v_final'], v_final)
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# test while loop that doesn't have any scan_outputs
M = np.int64(4)
cond = v1_initial < v2_initial
graph = helper.make_graph(nodes=[add1_node, neg_node, add2_node, less_node],
name="while_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[new_cond_out, sum1_out, sum2_out])
node_def = helper.make_node('Loop',
['M', 'cond', 'v1_initial', 'v2_initial'],
['v_final'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
v_final = [
np.array([16, 16], dtype=np.int32),
np.array([70, 70], dtype=np.int32)
]
np.testing.assert_almost_equal(output['v_final'], v_final)
# test for loop that doesn't run at all (M = 0)
# and the scan_outputs shape is not the same as the inputs
v1_initial = np.array([[1, 1, 1], [2, 2, 2]], dtype=np.int32)
v3_initial = np.array([[1, 1], [2, 2], [3, 3]], dtype=np.int32)
matmul_node = helper.make_node('MatMul',
inputs=['x', 'z'],
outputs=['product'])
x_in = helper.make_tensor_value_info('x', TensorProto.INT32, [None, None])
z_in = helper.make_tensor_value_info('z', TensorProto.INT32, [None, None])
sum1_out = helper.make_tensor_value_info('sum1', TensorProto.INT32,
[None, None])
z_out = helper.make_tensor_value_info('z', TensorProto.INT32, [None, None])
product_out = helper.make_tensor_value_info('product', TensorProto.INT32,
[None, None])
M = np.int64(0)
cond = True # value will be ignore because optional "cond" input will be skip
graph = helper.make_graph(nodes=[add1_node, matmul_node],
name="for_loop_graph",
inputs=[m_in, cond_in, x_in, z_in],
outputs=[cond_out, sum1_out, z_out, product_out])
node_def = helper.make_node('Loop', ['M', '', 'v1_initial', 'v3_initial'],
['v_final', 'scan_outputs'],
body=graph)
output = run_node(node_def, [M, cond, v1_initial, v3_initial])
v_final = [v1_initial, v3_initial]
scan_outputs = np.array([], dtype=np.int32).reshape(1, 0, 2, 2)
for i in range(len(output['v_final'])):
np.testing.assert_almost_equal(output['v_final'][i], v_final[i])
np.testing.assert_almost_equal(output['scan_outputs'], scan_outputs)
# verify infinite loop will get exception
M = 0 # value will be ignore because optional "M" input will be skip
cond = True # value will be ignore because optional "cond" input will be skip
graph = helper.make_graph(
nodes=[add1_node, neg_node, add2_node, add3_node, less_node],
name="while_loop_graph",
inputs=[m_in, cond_in, x_in, y_in],
outputs=[cond_out, sum1_out, sum2_out, sum3_out])
node_def = helper.make_node('Loop', ['', '', 'v1_initial', 'v2_initial'],
['v_final', 'scan_outputs'],
body=graph)
try:
output = run_node(node_def, [M, cond, v1_initial, v2_initial])
raise AssertionError("Expected RuntimeError not raise when Loop inputs " +
"M and cond are both not set at the same time")
except RuntimeError as e:
assert "M and cond in Loop are not set" in str(e)
def test_matmul_integer(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support MatMulInteger.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("MatMulInteger",
["A", "B", "a_zero_point", "b_zero_point"],
["Z"])
lower_bound = {np.uint8: 0, np.int8: -20}
for dtype in [np.uint8, np.int8]:
# A & B are 3-D tensor and a_zero_point & b_zero_point are scalar
A = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 3, 4),
dtype=dtype)
B = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 4, 6),
dtype=dtype)
a_zero_point = self._get_rnd_int(lower_bound[dtype], 20, dtype=dtype)
b_zero_point = self._get_rnd_int(lower_bound[dtype], 20, dtype=dtype)
A_minus_zero_point = np.subtract(A.astype(np.int32),
a_zero_point.astype(np.int32))
B_minus_zero_point = np.subtract(B.astype(np.int32),
b_zero_point.astype(np.int32))
z = np.matmul(A_minus_zero_point, B_minus_zero_point)
output = run_node(node_def, [A, B, a_zero_point, b_zero_point])
np.testing.assert_almost_equal(output["Z"], z)
# A & B are 4-D tensor and a_zero_point & b_zero_point are 1-D tensor
A = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 5, 3, 4),
dtype=dtype)
B = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 1, 4, 6),
dtype=dtype)
a_zero_point = self._get_rnd_int(lower_bound[dtype],
20,
shape=(A.shape[-2]),
dtype=dtype)
b_zero_point = self._get_rnd_int(lower_bound[dtype],
20,
shape=(B.shape[-1]),
dtype=dtype)
a_zero_point_with_reshape = np.reshape(a_zero_point, [A.shape[-2], 1])
A_minus_zero_point = np.subtract(
A.astype(np.int32), a_zero_point_with_reshape.astype(np.int32))
B_minus_zero_point = np.subtract(B.astype(np.int32),
b_zero_point.astype(np.int32))
z = np.matmul(A_minus_zero_point, B_minus_zero_point)
output = run_node(node_def, [A, B, a_zero_point, b_zero_point])
np.testing.assert_almost_equal(output["Z"], z)
node_def = helper.make_node("MatMulInteger", ["A", "B"], ["Z"])
for dtype in [np.uint8, np.int8]:
# A & B are 3-D tensor
A = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 3, 4),
dtype=dtype)
B = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 4, 6),
dtype=dtype)
z = np.matmul(A.astype(np.int32), B.astype(np.int32))
output = run_node(node_def, [A, B])
np.testing.assert_almost_equal(output["Z"], z)
# A & B are 4-D tensor
A = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 5, 3, 4),
dtype=dtype)
B = self._get_rnd_int(lower_bound[dtype],
20,
shape=(2, 1, 4, 6),
dtype=dtype)
z = np.matmul(A.astype(np.int32), B.astype(np.int32))
output = run_node(node_def, [A, B])
np.testing.assert_almost_equal(output["Z"], z)
def test_max(self):
node_def = helper.make_node("Max", ["X1", "X2", "X3", "X4"], ["Z"])
x1 = self._get_rnd_float32(shape=[10, 10])
x2 = self._get_rnd_float32(shape=[10, 10])
x3 = self._get_rnd_float32(shape=[10, 10])
x4 = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [x1, x2, x3, x4])
test_output = np.maximum(np.maximum(np.maximum(x1, x2), x3), x4)
np.testing.assert_almost_equal(output["Z"], test_output)
def _test_pooling(self,
input_shape,
kernel_shape,
strides=None,
dilations=None,
pads=None,
auto_pad=None,
ceil_mode=None,
count_include_pad=None,
pooling_type="MAX",
input_dtype=np.float32,
p=None):
op = "MaxPool" if pooling_type.upper().startswith("MAX") else \
"AveragePool" if pooling_type.upper() == "AVG" else "LpPool"
node_def_kwargs = {
"op_type": op,
"inputs": ["X"],
"outputs": ["Y"],
"kernel_shape": kernel_shape
}
if strides is not None:
node_def_kwargs["strides"] = strides
if dilations is not None:
node_def_kwargs["dilations"] = dilations
if pads is not None:
node_def_kwargs["pads"] = pads
if auto_pad is not None:
node_def_kwargs["auto_pad"] = auto_pad
pads = auto_pad
if ceil_mode is not None:
node_def_kwargs["ceil_mode"] = ceil_mode
else:
ceil_mode = 0
if count_include_pad is not None:
node_def_kwargs["count_include_pad"] = count_include_pad
if p is not None:
node_def_kwargs["p"] = p
node_def = helper.make_node(**node_def_kwargs)
if input_dtype == np.float32:
x = self._get_rnd_float32(shape=input_shape)
else:
x = self._get_rnd_int(low = np.iinfo(input_dtype).min,
high = np.iinfo(input_dtype).max,
shape=input_shape, dtype=input_dtype)
x = self._get_rnd_float32(shape=input_shape)
output = run_node(node_def, [x])
test_output = py_pool(x,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
padding=pads,
ceil_mode=ceil_mode,
pooling_type=pooling_type,
include_indices=False,
p=p)
np.testing.assert_almost_equal(output["Y"], test_output,
decimal=5 if pooling_type=="LP" else 7)
def test_max_pool_2d(self):
kernel_shape = [1, 2]
strides = [1, 2]
input_shape = [10, 10, 4, 4]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides)
def test_max_pool_2d_same_lower(self):
kernel_shape = [1, 2]
strides = [1, 2]
auto_pad = "SAME_LOWER"
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad)
def test_max_pool_2d_ceil_same_lower(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [2, 1]
strides = [1, 2]
auto_pad = "SAME_LOWER"
ceil_mode = 1
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad,
ceil_mode=ceil_mode)
def test_max_pool_2d_same_upper(self):
kernel_shape = [1, 2]
strides = [1, 2]
auto_pad = "SAME_UPPER"
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad)
def test_max_pool_2d_ceil(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
ceil_mode = 1
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
ceil_mode=ceil_mode)
def test_max_pool_2d_dilations(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
node_def = helper.make_node("MaxPool", ["X"], ["Y"],
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations)
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations)
def test_max_pool_2d_dilations_ceil(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations nor ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
ceil_mode = 1
input_shape = [10, 3, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
ceil_mode=ceil_mode)
def test_max_pool_2d_dilations_pads(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
pads = [1, 1, 2, 2]
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
pads=pads)
def test_max_pool_2d_dilations_ceil_pads(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations nor ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
pads = [1, 1, 2, 2]
ceil_mode = 1
input_shape = [10, 3, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
pads=pads,
ceil_mode=ceil_mode)
def test_max_pool_2d_dilations_same_lower(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
auto_pad = "SAME_LOWER"
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
auto_pad=auto_pad)
def test_max_pool_2d_dilations_same_upper(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations.".format(
defs.onnx_opset_version()))
kernel_shape = [2, 3]
strides = [4, 2]
dilations = [3, 5]
auto_pad = "SAME_UPPER"
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
auto_pad=auto_pad)
def test_max_pool_2d_dilations_ceil_pads_int8(self):
if legacy_opset_pre_ver(12):
raise unittest.SkipTest(
"ONNX version {} does not support int8 input type.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
pads = [1, 1, 2, 2]
ceil_mode = 1
input_shape = [10, 3, 23, 23]
self._test_pooling(input_shape=input_shape, kernel_shape=kernel_shape,
strides=strides, dilations=dilations, pads=pads,
ceil_mode=ceil_mode, input_dtype=np.int8)
def test_max_pool_3d(self):
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides)
def test_max_pool_3d_dilations_ceil_pads(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations nor ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
dilations = [3, 3, 3]
pads = [1, 1, 2, 2, 1, 1]
ceil_mode = 1
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
pads=pads,
ceil_mode=ceil_mode)
def test_max_pool_3d_dilations_same_lower(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 1, 2]
strides = [2, 2, 1]
dilations = [3, 2, 5]
auto_pad = "SAME_LOWER"
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
auto_pad=auto_pad)
def test_max_pool_1d_dilations_ceil_pads(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations nor ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3]
strides = [2]
dilations = [3]
pads = [1, 2]
ceil_mode = 1
input_shape = [10, 3, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
pads=pads,
ceil_mode=ceil_mode)
def test_max_pool_1d(self):
kernel_shape = [3]
strides = [2]
input_shape = [10, 3, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides)
def test_max_pool_with_argmax_2d_dilations_ceil_pads(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support dilations nor ceil mode.".format(
defs.onnx_opset_version()))
kernel_shape = [3, 3]
strides = [2, 2]
dilations = [3, 3]
pads = [1, 1, 2, 2]
ceil_mode = True
node_def = helper.make_node("MaxPool", ["X"], ["Y", "Ind"],
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
pads=pads,
ceil_mode=ceil_mode)
input_shape = [10, 1, 23, 23]
x = self._get_rnd_float32(shape=input_shape) - 2
output = run_node(node_def, [x])
test_output, test_ind = py_pool(x,
kernel_shape=kernel_shape,
strides=strides,
dilations=dilations,
padding=pads,
ceil_mode=ceil_mode,
pooling_type="MAX")
np.testing.assert_almost_equal(output["Y"], test_output)
np.testing.assert_almost_equal(output["Ind"], test_ind)
def test_max_pool_with_argmax_3d(self):
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
node_def = helper.make_node("MaxPool", ["X"], ["Y", "Ind"],
kernel_shape=kernel_shape,
strides=strides)
input_shape = [10, 1, 23, 23, 23]
x = self._get_rnd_float32(shape=input_shape)
self.assertRaises(RuntimeError, run_node, node_def, [x])
def test_max_pool_4d(self):
kernel_shape = [3, 3, 3, 3]
strides = [2, 2, 2, 2]
node_def = helper.make_node("MaxPool", ["X"], ["Y", "Ind"],
kernel_shape=kernel_shape,
strides=strides)
input_shape = [1, 1, 4, 4, 4, 4]
x = self._get_rnd_float32(shape=input_shape)
self.assertRaises(RuntimeError, run_node, node_def, [x])
def test_max_unpool(self):
input_shape = [10, 10, 4, 4]
x = self._get_rnd_float32(shape=input_shape)
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, input_shape)
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, input_shape)
node_def = helper.make_node("MaxPool", ["X"], ["Pool", "Indices"],
kernel_shape=[2, 2],
strides=[2, 2])
output_pool = run_node(node_def, [x])
node_def = helper.make_node("MaxUnpool", ["Pool", "Indices"], ["Y"],
kernel_shape=[2, 2],
strides=[2, 2])
output_unpool = run_node(node_def,
[output_pool["Pool"], output_pool["Indices"]])
test_output = np.zeros(input_shape)
for i1 in range(0, input_shape[0]):
for i2 in range(0, input_shape[1]):
for i3 in range(0, input_shape[2], 2):
for i4 in range(0, input_shape[3], 2):
max_val = float('-inf')
for j1 in range(i3, i3 + 2):
for j2 in range(i4, i4 + 2):
if x[i1][i2][j1][j2] > max_val:
max_val = x[i1][i2][j1][j2]
max_ind = (j1, j2)
j1, j2 = max_ind
test_output[i1][i2][j1][j2] = max_val
np.testing.assert_almost_equal(output_unpool["Y"], test_output)
def test_average_pool_1d(self):
kernel_shape = [3]
strides = [2]
input_shape = [10, 3, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="AVG")
def test_average_pool_2d(self):
kernel_shape = [1, 2]
strides = [1, 2]
input_shape = [10, 10, 4, 4]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="AVG")
def test_average_pool_2d_same_upper(self):
kernel_shape=[1, 2]
strides=[1, 2]
auto_pad="SAME_UPPER"
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad,
pooling_type="AVG")
def test_average_pool_3d(self):
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="AVG")
def test_lp2_pool_2d(self):
kernel_shape = [1, 2]
strides = [1, 2]
p = 2
input_shape = [10, 10, 4, 4]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="LP",
p=p)
def test_lp2_pool_2d_same_lower(self):
kernel_shape = [1, 2]
strides = [1, 2]
p = 2
auto_pad = "SAME_LOWER"
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad,
pooling_type="LP",
p=p)
def test_lp2_pool_2d_same_upper(self):
kernel_shape = [1, 2]
strides = [1, 2]
p = 2
auto_pad = "SAME_UPPER"
input_shape = [10, 10, 7, 7]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
auto_pad=auto_pad,
pooling_type="LP",
p=p)
def test_lp2_pool_2d_pads(self):
kernel_shape = [3, 3]
strides = [2, 2]
p = 2
pads = [1, 1, 2, 2]
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pads=pads,
pooling_type="LP",
p=p)
def test_lp2_pool_3d(self):
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
p = 2
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="LP",
p=p)
def test_lp2_pool_1d(self):
kernel_shape = [3]
strides = [2]
p = 2
input_shape = [10, 3, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="LP",
p=p)
def test_lp3_pool_2d_pads(self):
kernel_shape = [3, 3]
strides = [2, 2]
p = 3
pads = [1, 1, 2, 2]
input_shape = [10, 3, 24, 24]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pads=pads,
pooling_type="LP",
p=p)
def test_lp3_pool_3d(self):
kernel_shape = [3, 3, 3]
strides = [2, 2, 2]
p = 3
input_shape = [10, 3, 23, 23, 23]
self._test_pooling(input_shape=input_shape,
kernel_shape=kernel_shape,
strides=strides,
pooling_type="LP",
p=p)
def test_mean_variance_normalization(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest(
"ONNX version {} doesn't have test for MeanVarianceNormalization".
format(defs.onnx_opset_version()))
input_data = self._get_rnd_float32(shape=[2, 2, 2, 2])
# Calculate expected output data using formula:
# (Input - Mean)/SD
mean = np.mean(input_data, keepdims=1, axis=(0, 2, 3))
std = np.std(input_data, keepdims=1, axis=(0, 2, 3))
expected_output = (input_data - mean) / std
# Testing without "axes" argument should default to axes=[0,2,3]
node_def = helper.make_node("MeanVarianceNormalization", ["X"], ["Y"])
output = run_node(node_def, [input_data])
np.testing.assert_almost_equal(output["Y"], expected_output, decimal=5)
def test_min(self):
node_def = helper.make_node("Min", ["X1", "X2", "X3", "X4"], ["Z"])
x1 = self._get_rnd_float32(shape=[10, 10])
x2 = self._get_rnd_float32(shape=[10, 10])
x3 = self._get_rnd_float32(shape=[10, 10])
x4 = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [x1, x2, x3, x4])
test_output = np.minimum(np.minimum(np.minimum(x1, x2), x3), x4)
np.testing.assert_almost_equal(output["Z"], test_output)
def test_mul(self):
node_def = helper.make_node("Mul", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[5, 10, 5, 5])
y = self._get_rnd_float32(shape=[10, 1, 1])
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"],
np.multiply(x, y.reshape([1, 10, 1, 1])))
def test_mod(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest("ONNX version {} doesn't support Mod.".format(
defs.onnx_opset_version()))
x = self._get_rnd_float32(shape=[5, 5])
y = self._get_rnd_float32(shape=[5, 5])
node_def = helper.make_node("Mod", ["X", "Y"], ["Z"], fmod=0)
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.mod(x, y))
node_def = helper.make_node("Mod", ["X", "Y"], ["Z"], fmod=1)
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.fmod(x, y))
def test_neg(self):
node_def = helper.make_node("Neg", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.negative(x))
def test_non_zero(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support NonZero.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("NonZero", ["x"], ["y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
y = np.array(np.nonzero(x))
output = run_node(node_def, [x])
np.testing.assert_equal(output["y"], y)
def test_onehot(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support OneHot.".format(
defs.onnx_opset_version()))
indices = np.array([[0, 2], [1, 2], [0, 1]])
depth = np.int32(5)
on_value = 6.0
off_value = 2.0
values = np.array([off_value, on_value])
node_def = helper.make_node('OneHot',
inputs=['indices', 'depth', 'values'],
outputs=['y'],
axis=-1)
y = (np.arange(depth) == indices[..., None]).astype(int)
y = y * (on_value - off_value) + off_value
output = run_node(node_def, inputs=[indices, depth, values])
np.testing.assert_equal(output['y'], y)
def test_range(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest("ONNX version {} doesn't support Range.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Range", ['start', 'limit', 'delta'], ['y'])
# test positive_delta
start = self._get_rnd_int(low=0, high=3)
limit = self._get_rnd_int(low=10, high=30)
delta = np.int32(3)
output = run_node(node_def, [start, limit, delta])
np.testing.assert_equal(output['y'], range(start, limit, delta))
# test negative_delta
start = self._get_rnd_int(low=20, high=30)
limit = self._get_rnd_int(low=1, high=5)
delta = np.int32(-2)
output = run_node(node_def, [start, limit, delta])
np.testing.assert_equal(output['y'], range(start, limit, delta))
def test_resize(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest(
"ONNX version {} doesn't support Resize with attributes: " +
"coordinate_transformation_mode, cubic_coeff_a, exclude_outside, " +
"extrapolation_value, nearest_mode and inputs: roi and sizes".format(
defs.onnx_opset_version()))
data = np.reshape(np.arange(1, 101, dtype=np.float32), [1, 1, 10, 10])
roi = np.array([], dtype=np.float32)
# resize_nearest_round_prefer_ceil_align_corners_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode='align_corners',
mode='nearest',
nearest_mode='round_prefer_ceil')
scales = np.array([1, 1, 0.9, 0.9], dtype=np.float32)
expected = np.array(
[[[[1, 2, 3, 4, 6, 7, 8, 9, 10], [11, 12, 13, 14, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 26, 27, 28, 29, 30],
[31, 32, 33, 34, 36, 37, 38, 39, 40],
[51, 52, 53, 54, 56, 57, 58, 59, 60],
[61, 62, 63, 64, 66, 67, 68, 69, 70],
[71, 72, 73, 74, 76, 77, 78, 79, 80],
[81, 82, 83, 84, 86, 87, 88, 89, 90],
[91, 92, 93, 94, 96, 97, 98, 99, 100]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_nearest_round_prefer_ceil_align_corners_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode='align_corners',
mode='nearest',
nearest_mode='round_prefer_ceil')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1, 3, 4, 6, 7, 9, 10], [21, 23, 24, 26, 27, 29, 30],
[31, 33, 34, 36, 37, 39, 40], [51, 53, 54, 56, 57, 59, 60],
[61, 63, 64, 66, 67, 69, 70], [81, 83, 84, 86, 87, 89, 90],
[91, 93, 94, 96, 97, 99, 100]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_nearest_floor_asymmetric_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode='asymmetric',
mode='nearest',
nearest_mode='floor')
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[1, 2, 3, 4, 6, 7, 8, 9], [11, 12, 13, 14, 16, 17, 18, 19],
[21, 22, 23, 24, 26, 27, 28, 29], [31, 32, 33, 34, 36, 37, 38, 39],
[51, 52, 53, 54, 56, 57, 58, 59], [61, 62, 63, 64, 66, 67, 68, 69],
[71, 72, 73, 74, 76, 77, 78, 79], [81, 82, 83, 84, 86, 87, 88, 89]]]
],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_nearest_floor_asymmetric_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode='asymmetric',
mode='nearest',
nearest_mode='floor')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1, 2, 3, 5, 6, 8, 9], [11, 12, 13, 15, 16, 18, 19],
[21, 22, 23, 25, 26, 28, 29], [41, 42, 43, 45, 46, 48, 49],
[51, 52, 53, 55, 56, 58, 59], [71, 72, 73, 75, 76, 78, 79],
[81, 82, 83, 85, 86, 88, 89]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_nearest_floor_half_pixel_scales
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode='tf_half_pixel_for_nn',
mode='nearest',
nearest_mode='floor')
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[1, 2, 4, 5, 6, 7, 9, 10], [11, 12, 14, 15, 16, 17, 19, 20],
[31, 32, 34, 35, 36, 37, 39, 40], [41, 42, 44, 45, 46, 47, 49, 50],
[51, 52, 54, 55, 56, 57, 59, 60], [61, 62, 64, 65, 66, 67, 69, 70],
[81, 82, 84, 85, 86, 87, 89, 90], [91, 92, 94, 95, 96, 97, 99, 100]]]
],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_nearest_floor_half_pixel_sizes
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode='tf_half_pixel_for_nn',
mode='nearest',
nearest_mode='floor')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1, 3, 4, 6, 7, 8, 10], [21, 23, 24, 26, 27, 28, 30],
[31, 33, 34, 36, 37, 38, 40], [51, 53, 54, 56, 57, 58, 60],
[61, 63, 64, 66, 67, 68, 70], [71, 73, 74, 76, 77, 78, 80],
[91, 93, 94, 96, 97, 98, 100]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_linear_align_corners_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode="align_corners",
mode='linear')
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[
1., 2.2857141, 3.5714285, 4.857143, 6.142857, 7.428571, 8.714286,
10.
],
[
13.857142, 15.142857, 16.428572, 17.714287, 19., 20.285715,
21.571428, 22.857143
],
[
26.714287, 28., 29.285713, 30.571426, 31.857141, 33.142857,
34.428574, 35.714283
],
[
39.57143, 40.857143, 42.14286, 43.428574, 44.714287, 46.,
47.285717, 48.57143
],
[
52.428574, 53.714283, 55., 56.285713, 57.571426, 58.857143,
60.142857, 61.428566
],
[
65.28571, 66.57143, 67.85714, 69.14285, 70.428566, 71.71428, 73.,
74.28571
],
[
78.14286, 79.42857, 80.71428, 82., 83.28572, 84.57143, 85.85715,
87.14286
],
[
91., 92.28571, 93.57143, 94.85715, 96.14285, 97.42857, 98.71429,
100.
]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-6, atol=1e-6)
# resize_linear_align_corners_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode="align_corners",
mode='linear')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1., 2.5, 4., 5.5, 7., 8.5, 10.],
[16., 17.5, 19., 20.5, 22., 23.5, 25.],
[31., 32.5, 34., 35.5, 37., 38.5, 40.],
[46., 47.5, 49., 50.5, 52., 53.5, 55.],
[61., 62.5, 64., 65.5, 67., 68.5, 70.],
[76., 77.5, 79., 80.5, 82., 83.5, 85.],
[91., 92.5, 94., 95.5, 97., 98.5, 100.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_linear_asymmetric_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode="asymmetric",
mode='linear')
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[1., 2.25, 3.5, 4.75, 6., 7.25, 8.5, 9.75],
[13.5, 14.75, 16., 17.25, 18.5, 19.75, 21., 22.25],
[26., 27.25, 28.5, 29.75, 31., 32.25, 33.5, 34.75],
[38.5, 39.75, 41., 42.25, 43.5, 44.75, 46., 47.25],
[51., 52.25, 53.5, 54.75, 56., 57.25, 58.5, 59.75],
[63.5, 64.75, 66., 67.25, 68.5, 69.75, 71., 72.25],
[76., 77.25, 78.5, 79.75, 81., 82.25, 83.5, 84.75],
[88.5, 89.75, 91., 92.25, 93.5, 94.75, 96., 97.25]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_linear_asymmetric_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode="asymmetric",
mode='linear')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array([[
[[1., 2.4285715, 3.857143, 5.285714, 6.714286, 8.142857, 9.571428],
[15.285715, 16.714287, 18.142857, 19.571428, 21., 22.42857, 23.857141],
[29.571428, 31., 32.428574, 33.857143, 35.285717, 36.714287, 38.14286],
[43.857143, 45.28571, 46.714283, 48.14286, 49.571434, 51., 52.42857],
[
58.14286, 59.57143, 61.000004, 62.428574, 63.857143, 65.28572,
66.71429
], [72.42857, 73.85713, 75.28572, 76.71429, 78.14286, 79.57143, 81.],
[86.71429, 88.14285, 89.57143, 91., 92.42857, 93.85714, 95.28571]]
]],
dtype=np.float32
) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-6, atol=1e-6)
# resize_linear_half_pixel_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
mode='linear')
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[2.375, 3.625, 4.875, 6.125, 7.375, 8.625, 9.875, 11.125],
[14.875, 16.125, 17.375, 18.625, 19.875, 21.125, 22.375, 23.625],
[27.375, 28.625, 29.875, 31.125, 32.375, 33.625, 34.875, 36.125],
[39.875, 41.125, 42.375, 43.625, 44.875, 46.125, 47.375, 48.625],
[52.375, 53.625, 54.875, 56.125, 57.375, 58.625, 59.875, 61.125],
[64.875, 66.125, 67.375, 68.625, 69.875, 71.125, 72.375, 73.625],
[77.375, 78.625, 79.875, 81.125, 82.375, 83.625, 84.875, 86.125],
[89.875, 91.125, 92.375, 93.625, 94.875, 96.125, 97.375, 98.625]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_linear_half_pixel_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
mode='linear')
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array([[[[
3.357143, 4.785714, 6.214286, 7.642857, 9.071428, 10.5, 11.928572
], [
17.642857, 19.071428, 20.5, 21.92857, 23.357141, 24.785713, 26.214285
], [
31.928572, 33.357143, 34.785713, 36.214287, 37.642857, 39.071426, 40.5
], [
46.214287, 47.642857, 49.071426, 50.5, 51.928574, 53.357143, 54.785713
], [60.5, 61.928577, 63.357147, 64.78572, 66.21429, 67.64286, 69.07143
], [
74.78572, 76.21429, 77.64285, 79.07143, 80.50001, 81.92857, 83.35715
], [89.07143, 90.5, 91.928566, 93.35715, 94.78571, 96.21428, 97.64285]]]
],
dtype=np.float32
) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-6, atol=1e-6)
# resize_cubic_align_corners_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode="align_corners",
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[
1., 2.285714, 3.5714293, 4.857143, 6.142857, 7.4285717, 8.714287,
10.
],
[
13.857139, 15.142854, 16.42857, 17.714281, 18.999994, 20.28571,
21.571426, 22.857138
],
[
26.71429, 28.000004, 29.285723, 30.571436, 31.85715, 33.142864,
34.428577, 35.71429
],
[
39.57143, 40.857143, 42.142864, 43.428574, 44.714287, 46.000004,
47.28572, 48.57143
],
[
52.42857, 53.714287, 55., 56.285717, 57.571423, 58.857143,
60.14286, 61.42857
],
[
65.28571, 66.57144, 67.85715, 69.14285, 70.428566, 71.71429,
73.00001, 74.28571
],
[
78.14287, 79.42857, 80.7143, 82.00001, 83.28573, 84.571434,
85.857155, 87.14287
],
[
91., 92.28572, 93.57144, 94.85715, 96.14285, 97.42858, 98.714294,
100.
]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-1, atol=1e-6)
# resize_cubic_align_corners_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode="align_corners",
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1., 2.5, 4., 5.5, 7., 8.5, 10.],
[16., 17.5, 19., 20.5, 22., 23.5, 25.],
[31., 32.5, 34., 35.5, 37., 38.5, 40.],
[46., 47.5, 49., 50.5, 52., 53.5, 55.],
[61., 62.5, 64., 65.5, 67., 68.5, 70.],
[76., 77.5, 79., 80.5, 82., 83.5, 85.],
[91., 92.5, 94., 95.5, 97., 98.5, 100.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# resize_cubic_asymmetric_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode="asymmetric",
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[1., 2.25, 3.5, 4.75, 6., 7.25, 8.5, 9.832117],
[13.5, 14.75, 16., 17.25, 18.5, 19.75, 21., 22.332117],
[26., 27.25, 28.5, 29.75, 31., 32.25, 33.5, 34.83212],
[38.5, 39.75, 41., 42.25, 43.5, 44.75, 46., 47.332115],
[51., 52.25, 53.5, 54.75, 56., 57.25, 58.5, 59.83212],
[63.5, 64.75, 66., 67.25, 68.5, 69.75, 71., 72.332115],
[76., 77.25, 78.5, 79.75, 81., 82.25, 83.5, 84.832115],
[
89.32117, 90.57117, 91.82117, 93.07117, 94.32117, 95.57117,
96.82117, 98.15329
]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-1, atol=1e-6)
# resize_cubic_asymmetric_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode="asymmetric",
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[1., 2.4285715, 3.8571432, 5.285714, 6.7142863, 8.142857, 9.66485],
[
15.285712, 16.714287, 18.142855, 19.571426, 21., 22.428568,
23.950563
],
[
29.57143, 31.000004, 32.428574, 33.857147, 35.285713, 36.714283,
38.236282
],
[
43.857143, 45.285717, 46.714287, 48.142868, 49.571434, 50.999992,
52.52199
],
[
58.142864, 59.57144, 61.000004, 62.428585, 63.857155, 65.28572,
66.80771
],
[
72.428566, 73.85715, 75.28572, 76.714294, 78.14285, 79.57143,
81.09343
],
[
87.6485, 89.07708, 90.505646, 91.93422, 93.36279, 94.79135,
96.313354
]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-1, atol=1e-6)
# resize_cubic_half_pixel_scales
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([1, 1, 0.8, 0.8], dtype=np.float32)
expected = np.array([[
[[
1.8098788, 3.1112535, 4.3612537, 5.6112533, 6.8612533, 8.111254,
9.361254, 10.662629
],
[14.823625, 16.125, 17.375, 18.625, 19.875, 21.125, 22.375, 23.676373],
[27.323626, 28.625, 29.875, 31.125, 32.375, 33.625, 34.875, 36.176376],
[39.823627, 41.125, 42.375, 43.625, 44.875, 46.125, 47.375, 48.676376],
[52.323624, 53.625, 54.875, 56.125, 57.375, 58.625, 59.875, 61.176373],
[64.82362, 66.125, 67.375, 68.625, 69.875, 71.125, 72.375, 73.67638],
[77.32362, 78.625, 79.875, 81.125, 82.375, 83.625, 84.875, 86.17638],
[
90.33737, 91.63874, 92.88875, 94.13875, 95.38875, 96.63875,
97.88875, 99.190125
]]
]],
dtype=np.float32
) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-6, atol=1e-6)
# resize_cubic_half_pixel_sizes
node_def = helper.make_node("Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=1)
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array([[[
[2.52846, 4.0323663, 5.460938, 6.889509, 8.318081, 9.746653, 11.250559],
[
17.567522, 19.071426, 20.499996, 21.928568, 23.357141, 24.785715,
26.28962
],
[
31.853237, 33.357143, 34.785713, 36.21429, 37.64286, 39.07143,
40.575344
],
[46.13895, 47.642857, 49.071434, 50.5, 51.928566, 53.357147, 54.861053],
[
60.42467, 61.92858, 63.357147, 64.78572, 66.214294, 67.64287,
69.14677
],
[
74.710396, 76.214294, 77.64286, 79.07144, 80.50001, 81.92858,
83.432495
],
[89.749466, 91.253365, 92.68193, 94.1105, 95.53907, 96.96766, 98.47156]
]]],
dtype=np.float32
) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_allclose(output['Y'], expected, rtol=1e-2, atol=1e-6)
# crop_and_resize_nearest with scales
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
coordinate_transformation_mode='tf_crop_and_resize',
mode='nearest',
nearest_mode='round_prefer_ceil',
extrapolation_value=-20.0)
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 1.2, 1.7], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[46., 48., 49., -20., -20., -20., -20., -20.],
[56., 58., 59., -20., -20., -20., -20., -20.],
[66., 68., 69., -20., -20., -20., -20., -20.],
[76., 78., 79., -20., -20., -20., -20., -20.],
[86., 88., 89., -20., -20., -20., -20., -20.],
[96., 98., 99., -20., -20., -20., -20., -20.],
[-20., -20., -20., -20., -20., -20., -20., -20.],
[-20., -20., -20., -20., -20., -20., -20., -20.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_almost_equal(output["Y"], expected)
# crop_and_resize_nearest with sizes
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
coordinate_transformation_mode='tf_crop_and_resize',
mode='nearest',
nearest_mode='round_prefer_ceil',
)
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 1.2, 1.7], dtype=np.float32)
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[46., 48., 50., 0., 0., 0., 0.], [56., 58., 60., 0., 0., 0., 0.],
[66., 68., 70., 0., 0., 0., 0.], [76., 78., 80., 0., 0., 0., 0.],
[86., 88., 90., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_almost_equal(output["Y"], expected)
# crop_and_resize_linear with scales
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='tf_crop_and_resize',
extrapolation_value=20.0)
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 1.2, 1.7], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
expected = np.array(
[[[[42.4, 43.814285, 45.228573, 20., 20., 20., 20., 20.],
[52.685715, 54.100002, 55.514286, 20., 20., 20., 20., 20.],
[62.971436, 64.38572, 65.80001, 20., 20., 20., 20., 20.],
[73.25715, 74.67143, 76.08572, 20., 20., 20., 20., 20.],
[83.54286, 84.957146, 86.37143, 20., 20., 20., 20., 20.],
[93.82858, 95.24287, 96.65715, 20., 20., 20., 20., 20.],
[20., 20., 20., 20., 20., 20., 20., 20.],
[20., 20., 20., 20., 20., 20., 20., 20.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales])
np.testing.assert_allclose(output["Y"], expected, rtol=1e-6, atol=1e-6)
# crop_and_resize_linear with sizes
node_def = helper.make_node(
"Resize",
inputs=['X', 'roi', 'scales', 'sizes'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='tf_crop_and_resize',
extrapolation_value=50.0)
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 1.2, 1.7], dtype=np.float32)
scales = np.array([], dtype=np.float32)
sizes = np.array([1, 1, 7, 7], dtype=np.int64)
expected = np.array(
[[[[42.4, 44.05, 45.7, 50., 50., 50., 50.],
[54.4, 56.050003, 57.700005, 50., 50., 50., 50.],
[66.40001, 68.05, 69.700005, 50., 50., 50., 50.],
[78.40001, 80.05001, 81.700005, 50., 50., 50., 50.],
[90.40001, 92.05, 93.70001, 50., 50., 50., 50.],
[50., 50., 50., 50., 50., 50., 50.],
[50., 50., 50., 50., 50., 50., 50.]]]],
dtype=np.float32) # expected value is calculated by onnx-runtime
output = run_node(node_def, [data, roi, scales, sizes])
np.testing.assert_allclose(output["Y"], expected, rtol=1e-6, atol=1e-6)
def test_round(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest("ONNX version {} doesn't support Round.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Round", ["X"], ["Y"])
x = self._get_rnd_float32(-20.0, 20.0, shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.round(x))
def test_qLinearMatMul(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support QLinearMatMul.".format(
defs.onnx_opset_version()))
def qLinearMatMul(a, a_scale, a_zero_point, b, b_scale, b_zero_point,
y_scale, y_zero_point):
y_dtype = y_zero_point.dtype
# reshape 1-D a_scale, a_zero_point, y_scale and
# y_zero_point so it can broadcast in arithmetic
# operations later
a_scale_shape = a_scale.shape
if a_scale_shape and a_scale_shape[0] > 1:
a_scale = np.reshape(a_scale, [a_scale_shape[0], 1])
a_zero_point = np.reshape(a_zero_point, [a_scale_shape[0], 1])
y_scale_shape = y_scale.shape
if y_scale_shape and y_scale_shape[0] > 1:
y_scale = np.reshape(y_scale, [y_scale_shape[0], 1])
y_zero_point = np.reshape(y_zero_point, [y_scale_shape[0], 1])
# cast everything to float32
a = a.astype(np.float32)
a_zero_point = a_zero_point.astype(np.float32)
b = b.astype(np.float32)
b_zero_point = b_zero_point.astype(np.float32)
y_zero_point = y_zero_point.astype(np.float32)
# dequantize a and b
dequantized_a = np.subtract(a, a_zero_point)
dequantized_a = np.multiply(dequantized_a, a_scale)
dequantized_b = np.subtract(b, b_zero_point)
dequantized_b = np.multiply(dequantized_b, b_scale)
# matmul a and b
x = np.matmul(dequantized_a, dequantized_b)
# quantize x
y = np.divide(x, y_scale)
y = np.round(y)
y = np.add(y, y_zero_point)
y = np.clip(y, np.iinfo(y_dtype).min, np.iinfo(y_dtype).max)
y = y.astype(y_dtype)
return y
node_def = helper.make_node('QLinearMatMul', [
'a', 'a_scale', 'a_zero_point', 'b', 'b_scale', 'b_zero_point',
'y_scale', 'y_zero_point'
], ['y'])
for dtype in [np.int8, np.uint8]:
low = np.iinfo(dtype).min
high = np.iinfo(dtype).max
a = self._get_rnd_int(low, high, [3, 4, 5, 6], dtype)
a_scale = self._get_rnd_float32(-0.005, 0.005, [5])
a_zero_point = self._get_rnd_int(low, high, [5], dtype)
b = self._get_rnd_int(low, high, [3, 4, 6, 2], dtype)
b_scale = self._get_rnd_float32(-0.005, 0.005, [2])
b_zero_point = self._get_rnd_int(low, high, [2], dtype)
y_scale = self._get_rnd_float32(-0.05, 0.05, [5])
y_zero_point = self._get_rnd_int(low, high, [5], dtype)
y = qLinearMatMul(a, a_scale, a_zero_point, b, b_scale, b_zero_point,
y_scale, y_zero_point)
output = run_node(node_def, [
a, a_scale, a_zero_point, b, b_scale, b_zero_point, y_scale,
y_zero_point
])
np.testing.assert_almost_equal(output['y'], y)
def test_relu(self):
node_def = helper.make_node("Relu", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.maximum(x, 0))
def test_pad(self):
x = self._get_rnd_float32(shape=[100, 100])
if legacy_opset_pre_ver(11): # for opset = 1 or 2
# mode = constant
node_def = helper.make_node("Pad", ["X"], ["Y"],
mode="constant",
pads=[1, 1, 1, 1],
value=2.0)
output = run_node(node_def, [x])
y = np.pad(x, ((1, 1), (1, 1)), 'constant', constant_values=(2, 2))
np.testing.assert_almost_equal(output["Y"], y)
# mode = reflect and edge
for mode in ['edge', 'reflect']:
node_def = helper.make_node("Pad", ["X"], ["Y"],
mode=mode,
pads=[1, 1, 1, 1])
output = run_node(node_def, [x])
y = np.pad(x, ((1, 1), (1, 1)), mode)
np.testing.assert_almost_equal(output["Y"], y)
else: # for opset = 11
# mode = constant
node_def = helper.make_node("Pad", ["X", "pads", "constant_values"],
["Y"],
mode="constant")
pads = np.array([1, 1, 1, 1], dtype=np.int64)
constant_values = 2.0
output = run_node(node_def, [x, pads, constant_values])
y = np.pad(x, ((1, 1), (1, 1)), 'constant', constant_values=(2, 2))
np.testing.assert_almost_equal(output["Y"], y)
# mode = reflect and edge
for mode in ['edge', 'reflect']:
node_def = helper.make_node("Pad", ["X", "pads"], ["Y"], mode=mode)
output = run_node(node_def, [x, pads])
y = np.pad(x, ((1, 1), (1, 1)), mode)
np.testing.assert_almost_equal(output["Y"], y)
def test_qlinearconv(self):
if legacy_opset_pre_ver(10):
raise unittest.SkipTest(
"ONNX version {} doesn't support QLinearConv.".format(
defs.onnx_opset_version()))
# Test w_scale and w_zero_point as scalar
node_def = helper.make_node("QLinearConv",
inputs=[
"x", "x_scale", "x_zero_point", "w",
"w_scale", "w_zero_point", "y_scale",
"y_zero_point"
],
outputs=["Y"])
x = np.array([
[255, 174, 162, 25, 203, 168, 58],
[15, 59, 237, 95, 129, 0, 64],
[56, 242, 153, 221, 168, 12, 166],
[232, 178, 186, 195, 237, 162, 237],
[188, 39, 124, 77, 80, 102, 43],
[127, 230, 21, 83, 41, 40, 134],
[255, 154, 92, 141, 42, 148, 247],
],
dtype=np.uint8).reshape((1, 1, 7, 7))
x_scale = np.float32(0.00369204697)
x_zero_point = np.uint8(132)
w = np.array([0], dtype=np.uint8).reshape((1, 1, 1, 1))
w_scale = np.float32(0.00172794575)
w_zero_point = np.uint8(255)
y = np.array([
[0, 81, 93, 230, 52, 87, 197],
[240, 196, 18, 160, 126, 255, 191],
[199, 13, 102, 34, 87, 243, 89],
[23, 77, 69, 60, 18, 93, 18],
[67, 216, 131, 178, 175, 153, 212],
[128, 25, 234, 172, 214, 215, 121],
[0, 101, 163, 114, 213, 107, 8],
],
dtype=np.uint8).reshape((1, 1, 7, 7))
y_scale = np.float32(0.00162681262)
y_zero_point = np.uint8(123)
output = run_node(node_def, [
x, x_scale, x_zero_point, w, w_scale, w_zero_point, y_scale,
y_zero_point
])
np.testing.assert_almost_equal(output["Y"], y)
def test_quantize_linear(self):
node_def = helper.make_node("QuantizeLinear",
["x", "y_scale", "y_zero_point"], ["y"])
for x in [
self._get_rnd_float32(-512., 512., [2, 6]),
self._get_rnd_int(-512, 512, [2, 6])
]:
y_scale = self._get_rnd_float32(-10., 10.)
for y_zero_point in [
self._get_rnd_int(-128, 127, dtype=np.int8),
self._get_rnd_int(0, 255, dtype=np.uint8)
]:
y = np.divide(x, y_scale)
y = np.round(y)
y = np.add(y, y_zero_point)
if y_zero_point.dtype.type is np.int8:
y = np.clip(y, -128, 127).astype(np.int8)
else:
y = np.clip(y, 0, 255).astype(np.uint8)
output = run_node(node_def, [x, y_scale, y_zero_point])
np.testing.assert_almost_equal(output["y"], y)
def test_reciprocal(self):
node_def = helper.make_node("Reciprocal", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], 1.0 / x)
def test_reduce_l1(self):
node_def = helper.make_node("ReduceL1", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"],
np.linalg.norm(x, 1, (1, 2), True))
def test_reduce_log_sum_exp(self):
node_def = helper.make_node("ReduceLogSumExp", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.log(
np.sum(np.exp(x), axis=(1, 2),
keepdims=True)),
rtol=1e-3)
def test_reduce_max(self):
node_def = helper.make_node("ReduceMax", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.max(x, (1, 2), keepdims=True),
rtol=1e-3)
# test tensor(uint8), tensor(int8)
node_def = helper.make_node("ReduceMax", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_int(0, 100, [5, 10, 10, 3], np.uint8)
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.max(x, (1, 2), keepdims=True),
rtol=1e-3)
node_def = helper.make_node("ReduceMax", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_int(-100, 100, [5, 10, 10, 3], np.int8)
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.max(x, (1, 2), keepdims=True),
rtol=1e-3)
def test_reduce_mean(self):
node_def = helper.make_node("ReduceMean", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.mean(x, (1, 2), keepdims=True),
rtol=1e-3)
def test_reduce_min(self):
node_def = helper.make_node("ReduceMin", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.min(x, (1, 2), keepdims=True),
rtol=1e-3)
# test tensor(uint8), tensor(int8)
node_def = helper.make_node("ReduceMin", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_int(0, 100, [5, 10, 10, 3], np.uint8)
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.min(x, (1, 2), keepdims=True),
rtol=1e-3)
node_def = helper.make_node("ReduceMin", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_int(-100, 100, [5, 10, 10, 3], np.int8)
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.min(x, (1, 2), keepdims=True),
rtol=1e-3)
def test_reduce_prod(self):
node_def = helper.make_node("ReduceProd", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[1, 5, 5, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.prod(x, (1, 2), keepdims=True),
rtol=1e-3)
def test_reduce_sum(self):
node_def = helper.make_node("ReduceSum", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.sum(x, (1, 2), keepdims=True),
rtol=1e-3)
def test_reduce_sum_square(self):
node_def = helper.make_node("ReduceSumSquare", ["X"], ["Y"], axes=[1, 2])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"],
np.sum(np.square(x), (1, 2), keepdims=True),
rtol=1e-3)
def test_pow(self):
node_def = helper.make_node("Pow", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=1000) / 2.0 + 0.5
y = self._get_rnd_float32(shape=1000) / 2.0 + 0.5
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.power(x, y))
def test_reshape(self):
x = self._get_rnd_float32(shape=100)
shape = [10, 10]
if defs.onnx_opset_version() < 5:
node_def = helper.make_node("Reshape", ["X"], ["Z"], shape=shape)
output = run_node(node_def, [x])
else:
node_def = helper.make_node("Reshape", ["X", "Y"], ["Z"])
output = run_node(node_def, [x, shape])
np.testing.assert_almost_equal(output["Z"], x.reshape([10, 10]))
def test_reshape_with_copy(self):
x = self._get_rnd_float32(shape=[10, 20 * 30])
shape = [0, 20, 30]
if defs.onnx_opset_version() < 5:
node_def = helper.make_node("Reshape", ["X"], ["Z"], shape=shape)
output = run_node(node_def, [x])
else:
node_def = helper.make_node("Reshape", ["X", "Y"], ["Z"])
output = run_node(node_def, [x, shape])
np.testing.assert_almost_equal(output["Z"], x.reshape([10, 20, 30]))
def test_selu(self):
node_def = helper.make_node("Selu", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
alpha = 1.6732
gamma = 1.0507
x[x <= 0] = gamma * (alpha * np.exp(x[x <= 0]) - alpha)
x[x > 0] = gamma * x[x > 0]
np.testing.assert_allclose(output["Y"], x, rtol=1e-3, atol=1e-7)
def _run_scan_node(self,
initial,
x1,
x2,
input_shape,
output_shape,
scan_input_axes=None,
scan_input_directions=None,
scan_output_axes=None,
scan_output_directions=None,
sequence_lens=None,
directions=None):
"""
Subgraph looks like this.
[const1] state_in concat1_in concat2_in_
\ | \ /
\--------[Add] [Concat]
| |
| concat_out
| |
| [Add]----------[const1]
| |
| add_out_1
| |
| [Split]
| / | | \
state_out split1_out ... split4_out
"""
val_1 = helper.make_tensor(
name='const_tensor',
data_type=TensorProto.FLOAT,
dims=[1],
vals=[1],
)
constant_node = helper.make_node("Constant", [], ["const_1"], value=val_1)
state_add_node = helper.make_node("Add", ["state_in", "const_1"],
["state_out"])
concat_node = helper.make_node("Concat", ["concat1_in", "concat2_in"],
["concat_out"],
axis=0)
add_node = helper.make_node("Add", ["concat_out", "const_1"], ["add_out"])
split_node = helper.make_node(
"Split", ["add_out"],
["split1_out", "split2_out", "split3_out", "split4_out"])
state_in = helper.make_tensor_value_info('state_in', TensorProto.FLOAT, [1])
concat1_in = helper.make_tensor_value_info('concat1_in', TensorProto.FLOAT,
input_shape)
concat2_in = helper.make_tensor_value_info('concat2_in', TensorProto.FLOAT,
input_shape)
state_out = helper.make_tensor_value_info('state_out', TensorProto.FLOAT,
[1])
split1_out = helper.make_tensor_value_info('split1_out', TensorProto.FLOAT,
output_shape)
split2_out = helper.make_tensor_value_info('split2_out', TensorProto.FLOAT,
output_shape)
split3_out = helper.make_tensor_value_info('split3_out', TensorProto.FLOAT,
output_shape)
split4_out = helper.make_tensor_value_info('split4_out', TensorProto.FLOAT,
output_shape)
scan_body = helper.make_graph(
[constant_node, state_add_node, concat_node, add_node, split_node],
"scan_body",
[state_in, concat1_in, concat2_in],
[state_out, split1_out, split2_out, split3_out, split4_out],
)
node_kwargs = {
"op_type": "Scan",
"inputs": ["initial", "x1", "x2"],
"outputs": ["y", "z1", "z2", "z3", "z4"],
"num_scan_inputs": 2,
"body": scan_body
}
if sequence_lens is not None:
node_kwargs["inputs"] = ["" if sequence_lens is str else "seq_lens"
] + node_kwargs["inputs"]
if scan_input_axes is not None:
node_kwargs["scan_input_axes"] = scan_input_axes
if scan_input_directions is not None:
node_kwargs["scan_input_directions"] = scan_input_directions
if scan_output_axes is not None:
node_kwargs["scan_output_axes"] = scan_output_axes
if scan_output_directions is not None:
node_kwargs["scan_output_directions"] = scan_output_directions
if directions is not None:
node_kwargs["directions"] = directions
scan_node = helper.make_node(**node_kwargs)
if sequence_lens is None:
inputs = [initial, x1, x2]
else:
inputs = [sequence_lens, initial, x1, x2]
return run_node(scan_node, inputs)
def test_scan_v8(self):
if legacy_opset_pre_ver(8) or not legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[5, 1]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[5, 20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[5, 20, 6, 2])
directions = [0, 1]
sequence_lens = np.array([15, 20, 14, 18, 20]).astype(np.int32)
Y = initial + (np.shape(x1)[1] if sequence_lens is str else \
np.reshape(sequence_lens,[-1, 1]))
x1_out = x1 + 1
# left-right flip x2 (reverse direction)
x2_out = x2[:, ::-1] + 1
Z = np.concatenate([x1_out, x2_out], 2)
if sequence_lens is not str:
for batch in range(len(sequence_lens)):
# zero pad from the sequence_lens
shape = list(np.shape(Z[batch]))
seq_len = sequence_lens[batch]
zero_pad = np.zeros([shape[0] - seq_len] + shape[1:])
Z[batch] = np.concatenate([Z[batch][:seq_len], zero_pad])
output = self._run_scan_node(initial,
x1,
x2, [6, 4], [3, 2],
sequence_lens=sequence_lens,
directions=directions)
output_z = np.concatenate(
[output["z1"], output["z2"], output["z3"], output["z4"]], 2)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scan(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[2]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
Y = initial + np.shape(x1)[0]
Z = np.concatenate([x1, x2], 1) + 1
output = self._run_scan_node(initial, x1, x2, [6, 2], [3, 2])
output_z = np.concatenate(
[output["z1"], output["z2"], output["z3"], output["z4"]], 1)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scan_input_directions(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[1]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
Y = initial + np.shape(x1)[0]
Z = np.concatenate([x1[::-1], x2], 1) + 1
output = self._run_scan_node(initial,
x1,
x2, [6, 2], [3, 2],
scan_input_directions=[1, 0])
output_z = np.concatenate(
[output["z1"], output["z2"], output["z3"], output["z4"]], 1)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scan_input_axes(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[1]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
Y = initial + np.shape(x1)[1]
x1_transpose = np.transpose(x1, (1, 0, 2))
x2_transpose = np.transpose(x2, (1, 0, 2))
Z = np.concatenate([x1_transpose, x2_transpose], 1) + 1
output = self._run_scan_node(initial,
x1,
x2, [3, 2], [10, 2],
scan_input_axes=[1, 1])
output_z = np.concatenate(
[output["z1"], output["z2"], output["z3"], output["z4"]], 1)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scan_output_directions(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[1]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
Y = initial + np.shape(x1)[0]
Z = np.concatenate([x1, x2], 1) + 1
output = self._run_scan_node(initial,
x1,
x2, [6, 2], [3, 2],
scan_output_directions=[1, 0, 0, 1])
output_z = np.concatenate(
[output["z1"][::-1], output["z2"], output["z3"], output["z4"][::-1]], 1)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scan_output_axes(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} not supported.".format(
defs.onnx_opset_version()))
initial = self._get_rnd_int(0, 100, shape=[1]).astype(np.float32)
x1 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
x2 = self._get_rnd_float32(0, 1000, shape=[20, 6, 2])
Y = initial + np.shape(x1)[0]
Z = np.concatenate([x1, x2], 1) + 1
Z = np.transpose(Z, (1, 0, 2))
output = self._run_scan_node(initial,
x1,
x2, [10, 2], [3, 2],
scan_output_axes=[1, 1, 1, 1])
output_z = np.concatenate(
[output["z1"], output["z2"], output["z3"], output["z4"]], 0)
np.testing.assert_almost_equal(output["y"], Y)
np.testing.assert_almost_equal(output_z, Z)
def test_scatter_elements1(self):
data = np.array([[1.0, 2.0, 3.0, 4.0, 5.0]], dtype=np.float32)
indices = np.array([[1, 3]], dtype=np.int64)
updates = np.array([[1.1, 2.1]], dtype=np.float32)
axis = 1
ref_output = np.array([[1.0, 1.1, 3.0, 2.1, 5.0]], dtype=np.float32)
if legacy_opset_pre_ver(11):
node_def = helper.make_node("Scatter", ["data", "indices", "updates"],
["outputs"],
axis=axis)
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
else:
node_def = helper.make_node("ScatterElements",
["data", "indices", "updates"], ["outputs"],
axis=axis)
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
def test_scatter_elements2(self):
data = np.array([
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
],
dtype=np.float32)
indices = np.array([
[1, 0, 2],
[0, 2, 1],
], dtype=np.int64)
updates = np.array([
[1.0, 1.1, 1.2],
[2.0, 2.1, 2.2],
], dtype=np.float32)
ref_output = np.array([
[2.0, 1.1, 0.0],
[1.0, 0.0, 2.2],
[0.0, 2.1, 1.2],
],
dtype=np.float32)
if legacy_opset_pre_ver(11):
node_def = helper.make_node("Scatter", ["data", "indices", "updates"],
["outputs"])
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
else:
node_def = helper.make_node("ScatterElements",
["data", "indices", "updates"], ["outputs"])
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
def test_scatter_elements3(self):
# indices out of bounds
data = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=np.float32)
indices = np.array([[0, 1, 2]], dtype=np.int64)
updates = np.array([[1.1, 2.1, 3.1]], dtype=np.float32)
if legacy_opset_pre_ver(11):
node_def = helper.make_node("Scatter", ["data", "indices", "updates"],
["outputs"])
else:
node_def = helper.make_node("ScatterElements",
["data", "indices", "updates"], ["outputs"])
with np.testing.assert_raises(tf.errors.InvalidArgumentError):
output = run_node(node_def, [data, indices, updates])
def test_scatter_nd(self):
if legacy_opset_pre_ver(11):
raise unittest.SkipTest(
"ONNX version {} doesn't support ScatterND.".format(
defs.onnx_opset_version()))
# valid positve and negative indices for elements
data = np.array([1, 2, 3, 4, 5, 6, 7, 8], dtype=np.float32)
indices = np.array([[4], [3], [1], [7]], dtype=np.int64)
updates = np.array([9, 10, 11, 12], dtype=np.float32)
ref_output = np.array([1, 11, 3, 10, 9, 6, 7, 12], dtype=np.float32)
node_def = helper.make_node("ScatterND", ["data", "indices", "updates"],
["outputs"])
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# valid positive and negative indices for slices
data = np.reshape(np.arange(1, 25, dtype=np.float32), [2, 3, 4])
indices = np.array([[-2, -1], [1, 0]], dtype=np.int64)
updates = np.array([[39, 40, 41, 42], [43, 44, 45, 46]], dtype=np.float32)
ref_output = np.array(
[[[1, 2, 3, 4], [5, 6, 7, 8], [39, 40, 41, 42]],
[[43, 44, 45, 46], [17, 18, 19, 20], [21, 22, 23, 24]]],
dtype=np.float32)
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
indices = np.array([[-1]], dtype=np.int64)
updates = np.array([[[43, 44, 45, 46], [47, 48, 49, 50], [51, 52, 53, 54]]],
dtype=np.float32)
ref_output = np.array(
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
[[43, 44, 45, 46], [47, 48, 49, 50], [51, 52, 53, 54]]],
dtype=np.float32)
output = run_node(node_def, [data, indices, updates])
np.testing.assert_almost_equal(output["outputs"], ref_output)
# indices out of bounds
indices = np.array([[0, 1, 2], [-1, -1, -3], [-2, -3, -4], [0, 2, -5]],
dtype=np.int64)
updates = np.array([37, 52, 30, 39], dtype=np.float32)
with np.testing.assert_raises(tf.errors.InvalidArgumentError):
output = run_node(node_def, [data, indices, updates])
indices = np.array([[0, 1], [-1, -1], [-2, -4]], dtype=np.int64)
updates = np.array([[35, 36, 37, 38], [51, 52, 53, 54], [31, 32, 33, 34]],
dtype=np.float32)
with np.testing.assert_raises(tf.errors.InvalidArgumentError):
output = run_node(node_def, [data, indices, updates])
def test_shape(self):
node_def = helper.make_node("Shape", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_allclose(output["Y"], np.shape(x))
def test_shrink(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Shrink.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Shrink", ["X"], ["Y"], bias=1.5, lambd=1.5)
X = np.arange(-2.0, 2.1, dtype=np.float32)
Y = np.array([-0.5, 0, 0, 0, 0.5], dtype=np.float32)
output = run_node(node_def, [X])
np.testing.assert_almost_equal(output["Y"], Y)
def test_sigmoid(self):
node_def = helper.make_node("Sigmoid", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], 1 / (1 + np.exp(-x)))
def test_sign(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Sign.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Sign", ["X"], ["Y"])
x = self._get_rnd_float32(-10, 10, [3, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.sign(x))
def test_sinh(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Sinh.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Sinh", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.sinh(x))
def test_size(self):
node_def = helper.make_node("Size", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[5, 10, 10, 3])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.size(x))
def test_slice(self):
# test case 1 with normal inputs
axes = [0, 1, 2]
starts = [0, 0, 0]
ends = [2, 2, 2]
steps = [1, 1, 1]
if legacy_opset_pre_ver(10):
node_def = helper.make_node("Slice", ["X"], ["S"],
axes=axes,
starts=starts,
ends=ends)
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["S"], x[0:2, 0:2, 0:2])
else:
node_def = helper.make_node("Slice",
["X", "starts", "ends", "axes", "steps"],
["S"])
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x, starts, ends, axes, steps])
np.testing.assert_almost_equal(output["S"], x[0:2, 0:2, 0:2])
# test case 2 with negative, out-of-bound and default inputs
axes = [0, 2]
starts = [0, -7]
ends = [-8, 20]
if legacy_opset_pre_ver(10):
node_def = helper.make_node("Slice", ["X"], ["S"],
axes=axes,
starts=starts,
ends=ends)
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["S"], x[0:-8, :, -7:20])
else:
node_def = helper.make_node("Slice", ["X", "starts", "ends", "axes"],
["S"])
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x, starts, ends, axes])
np.testing.assert_almost_equal(output["S"], x[0:-8, :, -7:20])
# test case 3 with non-default steps
axes = [0, 1, 2]
starts = [0, 0, 0]
ends = [2, 2, 2]
steps = [2, -2, -1]
if legacy_opset_pre_ver(10) == False:
node_def = helper.make_node("Slice",
["X", "starts", "ends", "axes", "steps"],
["S"])
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x, starts, ends, axes, steps])
np.testing.assert_almost_equal(output["S"], x[0:2:2, 0:2:-2, 0:2:-1])
def test_softplus(self):
node_def = helper.make_node("Softplus", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.log(np.exp(x) + 1), decimal=5)
def test_softsign(self):
node_def = helper.make_node("Softsign", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[3, 4, 5])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], x / (1 + np.abs(x)))
def test_space_to_depth(self):
node_def = helper.make_node("SpaceToDepth", ["X"], ["Y"], blocksize=2)
x_shape = [1, 3, 2, 2]
x = self._get_rnd_float32(shape=x_shape)
output = run_node(node_def, [x])
x = np.transpose(x, (0, 2, 3, 1))
y = np.reshape(np.swapaxes(x.reshape(1, 1, 1, 1, 1, 12), 2, 3),
(1, 1, 1, 12))
y = np.transpose(y, (0, 3, 1, 2))
np.testing.assert_allclose(output["Y"], y, rtol=1e-3)
def test_split(self):
split = [3, 3, 4]
node_def = helper.make_node("Split", ["X"],
["Z%i" % i for i in range(len(split))],
axis=0,
split=split)
x = self._get_rnd_float32(shape=[100]).reshape([10, 10])
output = run_node(node_def, [x])
for a, b in zip(list(output), np.split(x, np.cumsum(split))[:-1]):
np.testing.assert_almost_equal(a, b)
# test axis out of bound
node_def = helper.make_node("Split", ["X"],
["Z%i" % i for i in range(len(split))],
axis=3,
split=split)
with np.testing.assert_raises(ValueError):
output = run_node(node_def, [x])
def test_sqrt(self):
node_def = helper.make_node("Sqrt", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000]) + 1.0
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.sqrt(x), decimal=5)
def test_squeeze(self):
node_def = helper.make_node("Squeeze", ["X"], ["Y"], axes=[2])
x = np.array([[[0], [1], [2]]])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.squeeze(x, axis=2))
def test_sub(self):
node_def = helper.make_node("Sub", ["X", "Y"], ["Z"])
x = self._get_rnd_float32(shape=[10, 10])
y = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [x, y])
np.testing.assert_almost_equal(output["Z"], np.subtract(x, y))
def test_sum(self):
node_def = helper.make_node("Sum", ["X1", "X2", "X3", "X4"], ["Z"])
x1 = self._get_rnd_float32(shape=[10, 10])
x2 = self._get_rnd_float32(shape=[10, 10])
x3 = self._get_rnd_float32(shape=[10, 10])
x4 = self._get_rnd_float32(shape=[10, 10])
output = run_node(node_def, [x1, x2, x3, x4])
test_output = x1 + x2 + x3 + x4
np.testing.assert_almost_equal(output["Z"], test_output)
def test_tanh(self):
node_def = helper.make_node("Tanh", ["X"], ["Y"])
x = self._get_rnd_float32(shape=[1000]) + 1.0
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.tanh(x), decimal=5)
def test_tfidf_vectorizer(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest(
"ONNX version {} doesn't support TfIdfVectorizer.".format(
defs.onnx_opset_version()))
def run_test_ints():
node_def = helper.make_node("TfIdfVectorizer", ["X"], ["Y"],
mode=mode,
min_gram_length=min_gram_len,
max_gram_length=max_gram_len,
max_skip_count=max_skip,
ngram_counts=ngram_counts,
ngram_indexes=ngram_indexes,
weights=weights,
pool_int64s=pool_int64s)
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], y)
def run_test_strings():
node_def = helper.make_node("TfIdfVectorizer", ["X"], ["Y"],
mode=mode,
min_gram_length=min_gram_len,
max_gram_length=max_gram_len,
max_skip_count=max_skip,
ngram_counts=ngram_counts,
ngram_indexes=ngram_indexes,
weights=weights,
pool_strings=pool_strings)
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], y)
# test 2d inputs with 3 elements, output contains 1-grams and 2-grams
x = np.array([[1, 1, 3, 3, 3, 7], [8, 6, 7, 5, 6, 8], [8, 6, 7, 5, 6,
8]]).astype(np.int32)
y = np.array([[0., 3., 0., 0., 0., 0., 0.], [0., 0., 1., 0., 1., 0., 1.],
[0., 0., 1., 0., 1., 0., 1.]]).astype(np.float32)
ngram_counts = np.array([0, 4]).astype(np.int64)
ngram_indexes = np.array([0, 1, 2, 3, 4, 5, 6]).astype(np.int64)
pool_int64s = np.array([2, 3, 5, 4, 5, 6, 7, 8, 6, 7]).astype(np.int64)
min_gram_len = 1
max_gram_len = 2
max_skip = 0
mode = 'TF'
weights = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
run_test_ints()
# test 1d inputs with indexes in non-default order, max_skip=3, output 2-grams
x = np.array([1, 1, 3, 3, 3, 7, 8, 6, 7, 5, 6, 8]).astype(np.int32)
y = np.array([0., 1., 0., 1., 0., 0., 2.]).astype(np.float32)
ngram_counts = np.array([0, 4]).astype(np.int64)
ngram_indexes = np.array([5, 0, 2, 4, 1, 6, 3]).astype(np.int64)
pool_int64s = np.array([2, 3, 5, 4, 5, 6, 7, 8, 6, 7]).astype(np.int64)
min_gram_len = 2
max_gram_len = 2
max_skip = 3
mode = 'TF'
weights = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
run_test_ints()
# test IDF mode with weights, max_skip=5, output contains 1-grams and 2-grams
x = np.array([[1, 1, 3, 3, 3, 7], [8, 6, 7, 5, 6, 8]]).astype(np.int32)
y = np.array([[0., 0.1, 0., 0., 0., 0., 0.],
[0., 0., 0.1, 0., 0.5, 0.5, 0.5]]).astype(np.float32)
ngram_counts = np.array([0, 4]).astype(np.int64)
ngram_indexes = np.array([0, 1, 2, 3, 4, 5, 6]).astype(np.int64)
pool_int64s = np.array([2, 3, 5, 4, 5, 6, 7, 8, 6, 7]).astype(np.int64)
min_gram_len = 1
max_gram_len = 2
max_skip = 5
mode = 'IDF'
weights = np.array([0.1, 0.1, 0.1, 0.1, 0.5, 0.5, 0.5])
run_test_ints()
# test strings inputs, max_skip=5, output contains 1-grams and 2-grams
x = np.array(['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e', 'c', 'f', 'e', 'd'])
y = np.array([0., 3., 1., 0., 1., 3., 1.]).astype(np.float32)
ngram_counts = np.array([0, 4]).astype(np.int64)
ngram_indexes = np.array([0, 1, 2, 3, 4, 5, 6]).astype(np.int64)
pool_strings = np.array(['x', 'b', 'f', 'y', 'f', 'e', 'c', 'd', 'e', 'c'])
min_gram_len = 1
max_gram_len = 2
max_skip = 5
mode = 'TF'
run_test_strings()
def test_thresholded_relu(self):
alpha = 2.0
node_def = helper.make_node("ThresholdedRelu", ["X"], ["Y"], alpha=alpha)
x = self._get_rnd_float32(-3.0, 3.0, [10])
y = np.clip(x, alpha, np.inf)
y[y == alpha] = 0
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], y)
def test_tile(self):
if legacy_onnx_pre_ver(1, 2):
raise unittest.SkipTest(
"The current version of ONNX does not record correctly the opset of Tile."
)
node_def = helper.make_node("Tile", ["X1", "X2"], ["Z"])
x = self._get_rnd_float32(shape=[3, 5, 5, 3])
repeats = [1, 1, 2, 1]
output = run_node(node_def, [x, repeats])
np.testing.assert_allclose(output["Z"], np.tile(x, repeats), rtol=1e-3)
def test_transpose(self):
node_def = helper.make_node("Transpose", ["X"], ["Y"], perm=[0, 2, 1])
x = self._get_rnd_float32(shape=[1000]).reshape([10, 10, 10])
output = run_node(node_def, [x])
np.testing.assert_almost_equal(output["Y"], np.transpose(x, (0, 2, 1)))
def test_topk(self):
x = np.arange(15, dtype=np.float32).reshape(3, 5)
values = np.array([[4, 3], [9, 8], [14, 13]], dtype=np.float32)
indices = np.array([[4, 3], [4, 3], [4, 3]], dtype=np.int64)
if legacy_opset_pre_ver(10): # for opset = 1
node_def = helper.make_node("TopK", ["x"], ["values", "indices"], k=2)
output = run_node(node_def, [x])
elif legacy_opset_pre_ver(11): # for opset = 10
k = np.array([2], dtype=np.int64)
node_def = helper.make_node("TopK", ["x", "k"], ["values", "indices"])
output = run_node(node_def, [x, k])
else: # for opset = 11
x = np.array([[3, 2, 5, 10, 7], [12, 15, 10, 7, 20], [21, 16, 5, 3, 6]],
dtype=np.float32)
values = np.array([[3, 2], [10, 7], [5, 3]], dtype=np.float32)
indices = np.array([[0, 1], [2, 3], [2, 3]], dtype=np.int64)
k = np.array([2], dtype=np.int64)
node_def = helper.make_node("TopK", ["x", "k"], ["values", "indices"],
largest=0,
sorted=0)
output = run_node(node_def, [x, k])
np.testing.assert_almost_equal(output["values"], values)
np.testing.assert_almost_equal(output["indices"], indices)
def test_where(self):
if legacy_opset_pre_ver(9):
raise unittest.SkipTest("ONNX version {} doesn't support Where.".format(
defs.onnx_opset_version()))
node_def = helper.make_node("Where", ["C", "X", "Y"], ["Z"])
c = np.array([[1, 0], [1, 1]], dtype=np.bool)
x = np.array([[1, 2], [3, 4]], dtype=np.float32)
y = np.array([[9, 8], [7, 6]], dtype=np.float32)
output = run_node(node_def, [c, x, y])
np.testing.assert_almost_equal(output["Z"], np.where(c, x, y))
if __name__ == '__main__':
unittest.main()