def test_code_add_transpose(self): idi = numpy.identity(2, dtype=numpy.float32) onx = OnnxTranspose(OnnxAdd('X', idi, op_version=get_opset_number_from_onnx()), output_names=['Y'], op_version=get_opset_number_from_onnx()) model_def = onx.to_onnx({'X': idi.astype(numpy.float32)}) oinf = OnnxInference(model_def, runtime='python') res = oinf.to_python(inline=False) self.assertNotEmpty(res) self.assertIsInstance(res, dict) self.assertEqual(len(res), 2) self.assertIn('onnx_pyrt_Ad_Addcst.pkl', res) self.assertIn('onnx_pyrt_main.py', res) cd = res['onnx_pyrt_main.py'] self.assertIn('def pyrt_Add(X, Ad_Addcst):', cd) self.assertIn('def run(self, X):', cd) # inline temp = get_temp_folder(__file__, "temp_code_add_transpose") res = oinf.to_python(inline=True, dest=temp) self.assertNotEmpty(res) name = os.path.join(temp, 'onnx_pyrt_main.py') self.assertExists(name) # test code test_code = """ X = numpy.array([[1, 2], [3, 4]], dtype=numpy.float32) oinf = OnnxPythonInference() Y = oinf.run(X) print(Y) """ X = numpy.array([[1, 2], [3, 4]], dtype=numpy.float32) exp = oinf.run({'X': X})['Y'] sexp = str(exp) self.auto_test_script(name, test_code, sexp)
def build_ort_transpose(perm, op_version=12): node = OnnxTranspose('x', perm=perm, op_version=op_version, output_names=['z']) onx = node.to_onnx(inputs=[('x', FloatTensorType())], target_opset=op_version) sess = InferenceSession(onx.SerializeToString()) return lambda x, y: sess.run(None, {'x': x})
def test_transpose2(self): from skl2onnx.algebra.onnx_ops import OnnxTranspose node = OnnxTranspose(OnnxTranspose('X', perm=[1, 0, 2]), perm=[1, 0, 2], output_names=['Y']) X = np.arange(2 * 3 * 4).reshape((2, 3, 4)).astype(np.float32) model_def = node.to_onnx({'X': X}) onnx.checker.check_model(model_def) res = self.predict_with_onnxruntime(model_def, X) assert_almost_equal(res['Y'], X)
def test_onnx_micro_runtime_transpose(self): opset = TestOnnxMicroRuntime.opset x = numpy.array([1, 2, 4, 5, 5, 4]).astype(numpy.float32).reshape( (3, 2)) cop = OnnxTranspose('X', perm=[1, 0], op_version=opset, output_names=['Y']) model_def = cop.to_onnx({'X': x}, target_opset=opset) rt = OnnxMicroRuntime(model_def) out = rt.run({'X': x}) self.assertEqual(x.T, out['Y'])
def test_onnxt_runtime_transpose(self): X = numpy.array( [[0, 1, 2, 3, 4], [1, -1, -2, 4, 5], [2, -2, -3, 5, -4]], dtype=numpy.float32) onx = OnnxTranspose('X', perm=[0, 1], output_names=['Y']) model_def = onx.to_onnx({'X': X.astype(numpy.float32)}) oinf = OnnxInference(model_def) got = oinf.run({'X': X}) self.assertEqual(list(sorted(got)), ['Y']) self.assertEqualArray(X, got['Y']) X = numpy.array( [[0, 1, 2, 3, 4], [1, -1, -2, 4, 5], [2, -2, -3, 5, -4]], dtype=numpy.float32) onx = OnnxTranspose('X', perm=[1, 0], output_names=['Y']) model_def = onx.to_onnx({'X': X.astype(numpy.float32)}) oinf = OnnxInference(model_def) got = oinf.run({'X': X}) self.assertEqual(list(sorted(got)), ['Y']) self.assertEqualArray(X.T, got['Y'])
[helper.make_tensor_value_info('X', TensorProto.FLOAT, (2, 3, 4))], [helper.make_tensor_value_info('Z', TensorProto.FLOAT, (2, 3, 4))], ) original_model = helper.make_model(graph, producer_name='onnx-examples') # Check the model and print Y's shape information onnx.checker.check_model(original_model) ##################################### # Which we translate into: from skl2onnx.algebra.onnx_ops import OnnxTranspose # noqa node = OnnxTranspose(OnnxTranspose('X', perm=[1, 0, 2], op_version=12), perm=[1, 0, 2], op_version=12) X = np.arange(2 * 3 * 4).reshape((2, 3, 4)).astype(np.float32) # numpy arrays are good enough to define the input shape model_def = node.to_onnx({'X': X}, target_opset=12) onnx.checker.check_model(model_def) ###################################### # Let's the output with onnxruntime def predict_with_onnxruntime(model_def, *inputs): import onnxruntime as ort sess = ort.InferenceSession(model_def.SerializeToString()) names = [i.name for i in sess.get_inputs()]
def live_decorrelate_transformer_converter(scope, operator, container): # shortcuts op = operator.raw_operator opv = container.target_opset out = operator.outputs # We retrieve the unique input. X = operator.inputs[0] # We guess its type. If the operator ingests float (or double), # it outputs float (or double). proto_dtype = guess_proto_type(X.type) dtype = guess_numpy_type(X.type) # Lines in comment specify the numpy computation # the ONNX code implements. # mean_ = numpy.mean(X, axis=0, keepdims=True) mean = OnnxReduceMean(X, axes=[0], keepdims=1, op_version=opv) # This is trick I often use. The converter automatically # chooses a name for every output. In big graph, # it is difficult to know which operator is producing which output. # This line just tells every node must prefix its ouputs with this string. # It also applies to all inputs nodes unless this method # was called for one of these nodes. mean.set_onnx_name_prefix('mean') # X2 = X - mean_ X2 = OnnxSub(X, mean, op_version=opv) # V = X2.T @ X2 / X2.shape[0] N = OnnxGatherElements(OnnxShape(X, op_version=opv), numpy.array([0], dtype=numpy.int64), op_version=opv) Nf = OnnxCast(N, to=proto_dtype, op_version=opv) # Every output involved in N and Nf is prefixed by 'N'. Nf.set_onnx_name_prefix('N') V = OnnxDiv(OnnxMatMul(OnnxTranspose(X2, op_version=opv), X2, op_version=opv), Nf, op_version=opv) V.set_onnx_name_prefix('V1') # V += numpy.identity(V.shape[0]) * self.alpha V = OnnxAdd(V, op.alpha * numpy.identity(op.nf_, dtype=dtype), op_version=opv) V.set_onnx_name_prefix('V2') # L, P = numpy.linalg.eig(V) LP = OnnxEig(V, eigv=True, op_version=opv) LP.set_onnx_name_prefix('LP') # Linv = L ** (-0.5) # Notation LP[0] means OnnxPow is taking the first output # of operator OnnxEig, LP[1] would mean the second one # LP is not allowed as it is ambiguous Linv = OnnxPow(LP[0], numpy.array([-0.5], dtype=dtype), op_version=opv) Linv.set_onnx_name_prefix('Linv') # diag = numpy.diag(Linv) diag = OnnxMul(OnnxEyeLike(numpy.zeros((op.nf_, op.nf_), dtype=numpy.int64), k=0, op_version=opv), Linv, op_version=opv) diag.set_onnx_name_prefix('diag') # root = P @ diag @ P.transpose() trv = OnnxTranspose(LP[1], op_version=opv) coef_left = OnnxMatMul(LP[1], diag, op_version=opv) coef_left.set_onnx_name_prefix('coef_left') coef = OnnxMatMul(coef_left, trv, op_version=opv) coef.set_onnx_name_prefix('coef') # Same part as before. Y = OnnxMatMul(X2, coef, op_version=opv, output_names=out[:1]) Y.set_onnx_name_prefix('Y') # The last line specifies the final output. # Every node involved in the computation is added to the ONNX # graph at this stage. Y.add_to(scope, container)
'two-transposes', [helper.make_tensor_value_info('X', TensorProto.FLOAT, (2, 3, 4))], [helper.make_tensor_value_info('Z', TensorProto.FLOAT, (2, 3, 4))], ) original_model = helper.make_model(graph, producer_name='onnx-examples') # Check the model and print Y's shape information onnx.checker.check_model(original_model) ##################################### # Which we translate into: from skl2onnx.algebra.onnx_ops import OnnxTranspose # noqa node = OnnxTranspose(OnnxTranspose('X', perm=[1, 0, 2]), perm=[1, 0, 2]) X = np.arange(2 * 3 * 4).reshape((2, 3, 4)).astype(np.float32) # numpy arrays are good enough to define the input shape model_def = node.to_onnx({'X': X}) onnx.checker.check_model(model_def) ###################################### # Let's the output with onnxruntime def predict_with_onnxruntime(model_def, *inputs): import onnxruntime as ort sess = ort.InferenceSession(model_def.SerializeToString()) names = [i.name for i in sess.get_inputs()] dinputs = {name: input for name, input in zip(names, inputs)}
def live_decorrelate_transformer_converter(scope, operator, container): op = operator.raw_operator opv = container.target_opset out = operator.outputs # We retrieve the unique input. X = operator.inputs[0] proto_dtype = guess_proto_type(X.type) dtype = guess_numpy_type(X.type) # new part # mean_ = numpy.mean(X, axis=0, keepdims=True) mean = OnnxReduceMean(X, axes=[0], keepdims=1, op_version=opv) mean.set_onnx_name_prefix('mean') # X2 = X - mean_ X2 = OnnxSub(X, mean, op_version=opv) # V = X2.T @ X2 / X2.shape[0] N = OnnxGatherElements(OnnxShape(X, op_version=opv), numpy.array([0], dtype=numpy.int64), op_version=opv) Nf = OnnxCast(N, to=proto_dtype, op_version=opv) Nf.set_onnx_name_prefix('N') V = OnnxDiv(OnnxMatMul(OnnxTranspose(X2, op_version=opv), X2, op_version=opv), Nf, op_version=opv) V.set_onnx_name_prefix('V1') # V += numpy.identity(V.shape[0]) * self.alpha V = OnnxAdd(V, op.alpha * numpy.identity(op.nf_, dtype=dtype), op_version=opv) V.set_onnx_name_prefix('V2') # L, P = numpy.linalg.eig(V) LP = OnnxEig(V, eigv=True, op_version=opv) LP.set_onnx_name_prefix('LP') # Linv = L ** (-0.5) Linv = OnnxPow(LP[0], numpy.array([-0.5], dtype=dtype), op_version=opv) Linv.set_onnx_name_prefix('Linv') # diag = numpy.diag(Linv) diag = OnnxMul(OnnxEyeLike(numpy.array([op.nf_, op.nf_], dtype=numpy.int64), k=0, op_version=opv), Linv, op_version=opv) diag.set_onnx_name_prefix('diag') # root = P @ diag @ P.transpose() trv = OnnxTranspose(LP[1], op_version=opv) coef_left = OnnxMatMul(LP[1], diag, op_version=opv) coef_left.set_onnx_name_prefix('coef_left') coef = OnnxMatMul(coef_left, trv, op_version=opv) coef.set_onnx_name_prefix('coef') # Same part as before. Y = OnnxMatMul(X2, coef, op_version=opv, output_names=out[:1]) Y.set_onnx_name_prefix('Y') Y.add_to(scope, container)