예제 #1
0
def build_ort_reducesumsquare(axes, op_version=14):  # opset=13, 14, ...
    node = OnnxReduceSumSquare('x',
                               axes=axes,
                               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_onnxt_runtime_reduce_sum_square(self):
        X = numpy.array([[2, 1], [0, 1]], dtype=float)

        onx = OnnxReduceSumSquare('X', output_names=['Y'], keepdims=0)
        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(numpy.sum(numpy.square(X)), got['Y'], decimal=6)

        onx = OnnxReduceSumSquare('X', output_names=['Y'], axes=1)
        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(
            numpy.sum(numpy.square(X), axis=1).ravel(), got['Y'].ravel())

        onx = OnnxReduceSumSquare('X', output_names=['Y'], axes=1, keepdims=1)
        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(
            numpy.sum(numpy.square(X), axis=1, keepdims=1).ravel(),
            got['Y'].ravel())
예제 #3
0
        def squareform_pdist(X, **kwargs):
            opv = TARGET_OPSET
            diff = OnnxSub('next_in',
                           'next',
                           output_names=['diff'],
                           op_version=opv)
            id_next = OnnxIdentity('next_in',
                                   output_names=['next_out'],
                                   op_version=opv)
            norm = OnnxReduceSumSquare(diff,
                                       output_names=['norm'],
                                       axes=[1],
                                       op_version=opv)
            flat = OnnxSqueezeApi11(norm,
                                    output_names=['scan_out'],
                                    axes=[1],
                                    op_version=opv)
            scan_body = id_next.to_onnx(
                OrderedDict([('next_in', FloatTensorType()),
                             ('next', FloatTensorType())]),
                outputs=[('next_out', FloatTensorType([None, None])),
                         ('scan_out', FloatTensorType([None]))],
                other_outputs=[flat])

            node = OnnxScan(X,
                            X,
                            output_names=['scan0_{idself}', 'scan1_{idself}'],
                            num_scan_inputs=1,
                            body=scan_body.graph,
                            op_version=opv,
                            **kwargs)
            return node[1]
예제 #4
0
def _onnx_square_error(target_opset=None,
                       dtype=numpy.float32,
                       weight_name=None):
    """
    Returns the ONNX graph for function
    :math:`Y = f(X1, X2) = \\lVert X1 - X2 \\rVert ^2` or
    :math:`Y = f(X1, X2) = \\lVert X1 - X2 \\rVert ^2 w` if
    *weight_name* is not None

    .. gdot::
        :script: DOT-SECTION

        from mlprodict.onnxrt import OnnxInference
        from onnxcustom.utils.onnx_function import function_onnx_graph

        model_onnx = function_onnx_graph('square_error')
        oinf = OnnxInference(model_onnx, inplace=False)

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import (OnnxSub, OnnxReduceSumSquare,
                                           OnnxReshape, OnnxReduceSum, OnnxMul)
    diff = OnnxSub('X1', 'X2', op_version=target_opset)
    if weight_name is None:
        res = OnnxReduceSumSquare(diff, op_version=target_opset)
    else:
        mul = OnnxMul(OnnxMul(diff, diff, op_version=target_opset),
                      OnnxReshape(weight_name,
                                  numpy.array([-1, 1], dtype=numpy.int64),
                                  op_version=target_opset),
                      op_version=target_opset)
        res = OnnxReduceSum(mul, op_version=target_opset)
    res = OnnxReshape(res,
                      numpy.array([-1], numpy.int64),
                      op_version=target_opset,
                      output_names=['Y'])
    var_type = dtype_to_var_type(dtype)
    varsx = [('X1', var_type([None, None])), ('X2', var_type([None, None]))]
    if weight_name is not None:
        varsx.append((weight_name, var_type([None])))
    onx = res.to_onnx(varsx,
                      outputs=[('Y', var_type())],
                      target_opset=target_opset)
    if weight_name is not None:
        onx = add_initializer(onx, weight_name, numpy.array([1], dtype=dtype))
    return onx
예제 #5
0
    def test_onnx_example_pdist(self):
        x = np.array([1, 2, 4, 5, 5, 4]).astype(np.float32).reshape((3, 2))

        opv = _TARGET_OPSET_
        diff = OnnxSub('next_in',
                       'next',
                       output_names=['diff'],
                       op_version=opv)
        id_next = OnnxIdentity('next_in',
                               output_names=['next_out'],
                               op_version=opv)
        norm = OnnxReduceSumSquare(diff,
                                   output_names=['norm'],
                                   axes=[1],
                                   op_version=opv)
        flat = OnnxSqueezeApi11(norm,
                                output_names=['scan_out'],
                                axes=[1],
                                op_version=opv)
        scan_body = id_next.to_onnx(OrderedDict([('next_in', x),
                                                 ('next', FloatTensorType())]),
                                    outputs=[
                                        ('next_out', FloatTensorType([3, 2])),
                                        ('scan_out', FloatTensorType([3]))
                                    ],
                                    other_outputs=[flat],
                                    target_opset=opv)

        sess = InferenceSession(scan_body.SerializeToString())
        res = sess.run(None, {'next_in': x, 'next': x[:1]})
        assert_almost_equal(x, res[0])
        exp = np.array([0., 18., 20.], dtype=np.float32)
        assert_almost_equal(exp, res[1])

        node = OnnxScan('x',
                        'x',
                        output_names=['y', 'z'],
                        num_scan_inputs=1,
                        body=scan_body.graph,
                        op_version=opv)
        model_def = node.to_onnx({'x': x},
                                 outputs=[('y', FloatTensorType([3, 2])),
                                          ('z', FloatTensorType([3, 3]))])
        try:
            onnx.checker.check_model(model_def)
        except ValidationError as e:
            if StrictVersion(onnx__version__) <= StrictVersion("1.5.0"):
                warnings.warn(e)
            else:
                raise e

        sess = InferenceSession(model_def.SerializeToString())
        res = sess.run(None, {'x': x})

        exp = squareform(pdist(x, metric="sqeuclidean"))
        assert_almost_equal(x, res[0])
        assert_almost_equal(exp, res[1])
예제 #6
0
    def test_onnx_example_pdist(self):
        x = np.array([1, 2, 4, 5, 5, 4]).astype(np.float32).reshape((3, 2))

        diff = OnnxSub('next_in', 'next', output_names=['diff'])
        id_next = OnnxIdentity('next_in', output_names=['next_out'])
        norm = OnnxReduceSumSquare(diff, output_names=['norm'], axes=[1])
        flat = OnnxSqueeze(norm, output_names=['scan_out'], axes=[1])
        scan_body = id_next.to_onnx(OrderedDict([('next_in', x),
                                                 ('next', FloatTensorType())]),
                                    outputs=[
                                        ('next_out', FloatTensorType([3, 2])),
                                        ('scan_out', FloatTensorType([3]))
                                    ],
                                    other_outputs=[flat])

        sess = InferenceSession(scan_body.SerializeToString())
        res = sess.run(None, {'next_in': x, 'next': x[:1]})
        assert_almost_equal(x, res[0])
        exp = np.array([0., 18., 20.], dtype=np.float32)
        assert_almost_equal(exp, res[1])

        node = OnnxScan('x',
                        'x',
                        output_names=['y', 'z'],
                        num_scan_inputs=1,
                        body=scan_body.graph)
        model_def = node.to_onnx({'x': x},
                                 outputs=[('y', FloatTensorType([3, 2])),
                                          ('z', FloatTensorType([3, 3]))])
        try:
            onnx.checker.check_model(model_def)
        except ValidationError as e:
            if sys.platform.startswith("win"):
                # schema information in onnx is incomplete on Windows
                warnings.warn(e)
            else:
                raise e

        sess = InferenceSession(model_def.SerializeToString())
        res = sess.run(None, {'x': x})

        exp = squareform(pdist(x, metric="sqeuclidean"))
        assert_almost_equal(x, res[0])
        assert_almost_equal(exp, res[1])
예제 #7
0
        def conv(scope, operator, container):
            X = operator.inputs[0]
            out = operator.outputs
            op = operator.raw_operator

            C = op.cluster_centers_
            C2 = row_norms(C, squared=True)

            N = X.type.shape[0]
            zeros = np.zeros((N, ))

            rs = OnnxReduceSumSquare(X, axes=[1], keepdims=1)
            z = OnnxAdd(rs, OnnxGemm(X, C, zeros, alpha=-2., transB=1))
            y2 = OnnxAdd(C2, z)
            lo = OnnxArgMin(y2, axis=1, keepdims=0, output_names=out[:1])
            y2s = OnnxSqrt(y2, output_names=out[1:])

            lo.add_to(scope, container)
            y2s.add_to(scope, container)
        def conv(scope, operator, container):
            X = operator.inputs[0]
            out = operator.outputs
            op = operator.raw_operator
            dtype = guess_numpy_type(X.type)

            C = op.cluster_centers_
            C2 = row_norms(C, squared=True).astype(dtype)
            C = C.astype(dtype)

            rs = OnnxReduceSumSquare(X,
                                     axes=[1],
                                     keepdims=1,
                                     op_version=container.target_opset)

            N = X.type.shape[0]
            if isinstance(N, int):
                zeros = np.zeros((N, ))
            else:
                zeros = OnnxMul(rs,
                                np.array([0], dtype=np.float32),
                                op_version=container.target_opset)

            z = OnnxAdd(rs,
                        OnnxGemm(X,
                                 C,
                                 zeros,
                                 alpha=-2.,
                                 transB=1,
                                 op_version=container.target_opset),
                        op_version=container.target_opset)
            y2 = OnnxAdd(C2, z, op_version=container.target_opset)
            lo = OnnxArgMin(y2,
                            axis=1,
                            keepdims=0,
                            output_names=out[:1],
                            op_version=container.target_opset)
            y2s = OnnxSqrt(y2,
                           output_names=out[1:],
                           op_version=container.target_opset)

            lo.add_to(scope, container)
            y2s.add_to(scope, container)
예제 #9
0
def _onnx_n_penalty_elastic_error(target_opset=None,
                                  dtype=numpy.float32,
                                  weight_name=None,
                                  l1_weight=0.01,
                                  l2_weight=0.01,
                                  n_tensors=1,
                                  loss_shape=(1, 1)):
    """
    Returns the ONNX graph for function
    :math:`Y = f(W) = \\beta \\lVert W \\rVert +
    \\alpha \\lVert W \\rVert^2`
    *l1_weight* is :math:`\\beta` and
    *l2_weight* is :math:`\\alpha`.
    It does that for *n_tensors* and adds all of the results
    to an input loss.

    .. gdot::
        :script: DOT-SECTION

        from mlprodict.onnxrt import OnnxInference
        from onnxcustom.utils.onnx_function import function_onnx_graph

        model_onnx = function_onnx_graph(
            'n_penalty_elastic_error', n_tensors=2)
        oinf = OnnxInference(model_onnx, inplace=False)

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import (OnnxMul, OnnxAdd,
                                           OnnxReduceSumSquare, OnnxReduceSum,
                                           OnnxAbs, OnnxReshape)

    if n_tensors <= 0:
        raise ValueError(  # pragma: no cover
            "This function is useless if the number of tensors is null.")

    var_type = dtype_to_var_type(dtype)
    varsx = [('loss', var_type(loss_shape))]
    names = ['loss']
    for n in range(n_tensors):
        name = 'W%d' % n
        abs_diff = OnnxAbs(name, op_version=target_opset)
        res_l1 = OnnxReduceSum(abs_diff, op_version=target_opset)
        # res2_l1 = OnnxSign(diff, op_version=target_opset)
        res_l2 = OnnxReduceSumSquare(name, op_version=target_opset)
        # res2_l2 = diff
        res = OnnxAdd(OnnxMul(res_l1,
                              numpy.array([l1_weight], dtype=dtype),
                              op_version=target_opset),
                      OnnxMul(res_l2,
                              numpy.array([l2_weight], dtype=dtype),
                              op_version=target_opset),
                      op_version=target_opset)
        names.append(res)
        varsx.append(('W%d' % n, var_type()))

    if len(names) == 2:
        res = OnnxAdd(*names, op_version=target_opset)
    else:
        res = OnnxAdd(names[1], names[2], op_version=target_opset)
        for i in range(3, len(names)):
            res = OnnxAdd(res, names[i], op_version=target_opset)
        res = OnnxAdd(names[0], res, op_version=target_opset)

    res = OnnxReshape(res,
                      numpy.array([-1], numpy.int64),
                      op_version=target_opset,
                      output_names=['Y'])
    onx = res.to_onnx(varsx,
                      outputs=[('Y', var_type([None]))],
                      target_opset=target_opset)
    return onx
예제 #10
0
def _onnx_grad_penalty_elastic_error(target_opset=None,
                                     dtype=numpy.float32,
                                     l1_weight=0.01,
                                     l2_weight=0.01):
    """
    Returns the ONNX graph for function
    :math:`Y = f(W) = \\beta \\lVert W \\rVert +
    \\alpha \\lVert W \\rVert^2`
    *l1_weight* is :math:`\\beta` and
    *l2_weight* is :math:`\\alpha`.

    .. gdot::
        :script: DOT-SECTION

        from mlprodict.onnxrt import OnnxInference
        from onnxcustom.utils.onnx_function import function_onnx_graph

        model_onnx = function_onnx_graph('grad_penalty_elastic_error')
        oinf = OnnxInference(model_onnx, inplace=False)

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import (OnnxMul, OnnxAdd,
                                           OnnxReduceSumSquare, OnnxReduceSum,
                                           OnnxSign, OnnxAbs, OnnxReshape)
    diff = 'X'
    abs_diff = OnnxAbs(diff, op_version=target_opset)
    res_l1 = OnnxReduceSum(abs_diff, op_version=target_opset)
    res2_l1 = OnnxSign(diff, op_version=target_opset)
    res_l2 = OnnxReduceSumSquare(diff, op_version=target_opset)
    res2_l2 = diff

    res = OnnxAdd(OnnxMul(res_l1,
                          numpy.array([l1_weight], dtype=dtype),
                          op_version=target_opset),
                  OnnxMul(res_l2,
                          numpy.array([l2_weight], dtype=dtype),
                          op_version=target_opset),
                  op_version=target_opset)
    res = OnnxReshape(res,
                      numpy.array([-1], numpy.int64),
                      op_version=target_opset,
                      output_names=['Y'])

    res2 = OnnxAdd(OnnxMul(res2_l1,
                           numpy.array([l1_weight], dtype=dtype),
                           op_version=target_opset),
                   OnnxMul(res2_l2,
                           numpy.array([l2_weight * (2)], dtype=dtype),
                           op_version=target_opset),
                   op_version=target_opset,
                   output_names=['Y_grad'])

    var_type = dtype_to_var_type(dtype)
    varsx = [('X', var_type([None, None]))]
    onx = res.to_onnx(varsx,
                      outputs=[('Y', var_type([None])),
                               ('Y_grad', var_type())],
                      target_opset=target_opset,
                      other_outputs=[res2])
    return onx