Example #1
0
def _onnx_zero(target_opset=None, dtype=numpy.float32):
    """
    Returns the ONNX graph for function
    :math:`Y = X * 0`.

    .. gdot::
        :script: DOT-SECTION

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

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

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import OnnxMul
    res = OnnxMul('X',
                  numpy.array([0], dtype=dtype),
                  op_version=target_opset,
                  output_names=['Y'])
    var_type = dtype_to_var_type(dtype)
    varsx = [('X', var_type())]
    onx = res.to_onnx(varsx,
                      outputs=[('Y', var_type())],
                      target_opset=target_opset)
    return onx
Example #2
0
 def test_grad_helper_mul(self):
     opv = opset
     xi = OnnxIdentity('X', op_version=opv)
     node = OnnxMul(xi, xi, op_version=opv, output_names=['Y'])
     onx = node.to_onnx({'X': FloatTensorType([None, 10])},
                        {'Y': FloatTensorType([None, 10])},
                        target_opset=opv)
     new_onx = onnx_derivative(onx)
     self.check_runtime(new_onx, 'test_grad_helper_mul')
Example #3
0
def build_leaky_relu_decomposed_greater(alpha=0.5, target_opset=15):
    signo = OnnxGreater('X',
                        numpy.array([0], dtype=numpy.float32),
                        op_version=target_opset)
    sign = OnnxCast(signo, to=TensorProto.FLOAT, op_version=target_opset)
    fact = OnnxAdd(OnnxMul(sign,
                           numpy.array([1 - alpha], dtype=numpy.float32),
                           op_version=target_opset),
                   numpy.array([alpha], dtype=numpy.float32),
                   op_version=target_opset)
    x = OnnxMul('X', fact, op_version=target_opset, output_names=['Y'])
    return x.to_onnx({'X': FloatTensorType()},
                     outputs={'Y': FloatTensorType()},
                     target_opset=target_opset)
    def test_onnxruntime_bug(self):
        rnd = numpy.random.randn(3, 20, 20).astype(numpy.float32)
        bni = (numpy.random.random((20, 20)).astype(  # pylint: disable=E1101
            numpy.float32) >= 0.7).astype(numpy.float32)
        mul = rnd * bni
        isn = any(numpy.isnan(mul.ravel()))
        self.assertFalse(isn)

        node = OnnxMul('X', bni, output_names=['Y4'],
                       op_version=TARGET_OPSET)
        onx = node.to_onnx({'X': rnd})
        for rt in ['python', 'onnxruntime1']:
            with self.subTest(runtime=rt):
                oinf = OnnxInference(onx, runtime=rt)
                y = oinf.run({'X': rnd})['Y4']
                self.assertEqualArray(mul, y)
Example #5
0
def build_leaky_relu_decomposed(alpha=0.5, target_opset=15):
    signo = OnnxSign('X', op_version=target_opset)
    sign = OnnxDiv(OnnxAdd(signo,
                           numpy.array([1], dtype=numpy.float32),
                           op_version=target_opset),
                   numpy.array([2], dtype=numpy.float32),
                   op_version=target_opset)
    fact = OnnxAdd(OnnxMul(sign,
                           numpy.array([1 - alpha], dtype=numpy.float32),
                           op_version=target_opset),
                   numpy.array([alpha], dtype=numpy.float32),
                   op_version=target_opset)
    x = OnnxMul('X', fact, op_version=target_opset, output_names=['Y'])
    return x.to_onnx({'X': FloatTensorType()},
                     outputs={'Y': FloatTensorType()},
                     target_opset=target_opset)
Example #6
0
def _onnx_grad_square_error(target_opset=None,
                            dtype=numpy.float32,
                            weight_name=None):
    """
    Returns the ONNX graph for the gradient of 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('grad_square_error')
        oinf = OnnxInference(model_onnx, inplace=False)

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import OnnxSub, OnnxMul, OnnxReshape
    diff = OnnxSub('X1', 'X2', op_version=target_opset)
    if weight_name is None:
        res = OnnxMul(diff,
                      numpy.array([-2], dtype=dtype),
                      op_version=target_opset,
                      output_names=['Y_grad'])
    else:
        res = OnnxMul(OnnxMul(diff,
                              numpy.array([-2], dtype=dtype),
                              op_version=target_opset),
                      OnnxReshape(weight_name,
                                  numpy.array([-1, 1], dtype=numpy.int64),
                                  op_version=target_opset),
                      op_version=target_opset,
                      output_names=['Y_grad'])
    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_grad', 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
Example #7
0
def build_ort_op(op_version=14, save=None, slices=None):  # opset=13, 14, ...
    if slices is None:
        starts = numpy.array([1, 1], dtype=numpy.int64)
        ends = numpy.array([-1, -1], dtype=numpy.int64)
        axes = None
    else:
        starts, ends = slices
        if starts[0] is None:
            indexes = [i for i in range(len(starts)) if starts[i] is not None]
            starts = numpy.array([n for n in starts if n is not None],
                                 dtype=numpy.int64)
            ends = numpy.array([n for n in ends if n is not None],
                               dtype=numpy.int64)
            axes = numpy.array(indexes, dtype=numpy.int64)
        else:
            starts = numpy.array(starts, dtype=numpy.int64)
            ends = numpy.array(ends, dtype=numpy.int64)
            axes = None

    if axes is None:
        node1 = OnnxSlice('X', starts, ends, op_version=op_version)
    else:
        node1 = OnnxSlice('X', starts, ends, axes, op_version=op_version)
    node2 = OnnxAdd(node1,
                    numpy.array([1], dtype=numpy.float32),
                    op_version=op_version)
    if axes is None:
        node3 = OnnxSlice(node2, starts, ends, op_version=op_version)
    else:
        node3 = OnnxSlice(node2, starts, ends, axes, op_version=op_version)
    node4 = OnnxMul(node3,
                    numpy.array([2], dtype=numpy.float32),
                    op_version=op_version,
                    output_names=['Y'])
    onx = node4.to_onnx(inputs=[('X', FloatTensorType([None, None]))],
                        target_opset=op_version)
    return onx
Example #8
0
 def get_onnx_mul(self):
     mul = OnnxMul('X', 'X', output_names=['Y'])
     onx = mul.to_onnx(inputs=[('X', FloatTensorType())])
     return onx.SerializeToString()
Example #9
0
def build_ort_op(op_version=14, save=None, **kwargs):  # opset=13, 14, ...
    slices = kwargs['slices']
    slice1, slice2 = slices
    slice1 = slice(0, None) if slice1 is None else slice(*slice1)
    slice2 = slice(0, None) if slice2 is None else slice(*slice2)

    axes = []
    starts = []
    ends = []
    for i in [0, 1]:
        if slices[i] is None:
            continue
        axes.append(i)
        starts.append(slices[i][0])
        ends.append(slices[i][1])
    starts = numpy.array(starts, dtype=numpy.int64)
    ends = numpy.array(ends, dtype=numpy.int64)
    axes = numpy.array(axes, dtype=numpy.int64)
    node1 = OnnxSlice('X', starts, ends, axes, op_version=op_version)
    node2 = OnnxAdd(node1,
                    numpy.array([1], dtype=numpy.float32),
                    op_version=op_version)
    node3 = OnnxSlice(node2, starts, ends, axes, op_version=op_version)
    node4 = OnnxMul(node3,
                    numpy.array([2], dtype=numpy.float32),
                    op_version=op_version,
                    output_names=['Y'])
    onx = node4.to_onnx(inputs=[('X', FloatTensorType([None, None]))],
                        target_opset=op_version)
    sess = InferenceSession(onx.SerializeToString(),
                            providers=["CPUExecutionProvider"])
    if save is not None:
        with open(save, "wb") as f:
            f.write(onx.SerializeToString())

    def npy_fct(x):
        return ((x[slice1, slice2] + 1)[slice1, slice2] * 2).copy()

    rnd = numpy.random.randn(10, 10).astype(numpy.float32)
    expected = npy_fct(rnd)
    got = sess.run(None, {'X': rnd})[0]
    try:
        assert_almost_equal(expected, got)
    except AssertionError as e:
        raise AssertionError("kwargs=%r slice1=%r slice2=%r shapes=%r ? %r "
                             "(x[slice1, slice2].shape)=%r" %
                             (kwargs, slice1, slice2, expected.shape,
                              got.shape, rnd[slice1, slice2].shape)) from e

    if get_device().upper() == 'GPU':
        sessg = InferenceSession(onx.SerializeToString(),
                                 providers=["CUDAExecutionProvider"])
        io_binding = sessg.io_binding()._iobinding
        device = get_ort_device('cuda:0')

        def run_gpu(x):
            io_binding.bind_input('X', device, numpy.float32, x.shape(),
                                  x.data_ptr())
            io_binding.bind_output('Y', device)
            return sessg._sess.run_with_iobinding(io_binding, None)

        return onx, lambda x: sess.run(None, {'X': x}), npy_fct, run_gpu
    else:
        return onx, lambda x: sess.run(None, {'X': x}), npy_fct, None
Example #10
0
def _onnx_grad_loss_square_error(target_opset=None,
                                 dtype=numpy.float32,
                                 weight_name=None,
                                 multiply=2):
    """
    Returns the ONNX graph for function
    :math:`Y = f(X1, X2) = \\lVert (X1 - X2) \\rVert ^2` or
    :math:`Y = f(X1, X2) = \\lVert (\\sqrt{w}(X1 - X2) \\rVert ^2 w` if
    *weight_name* is not None and its gradient.

    .. gdot::
        :script: DOT-SECTION

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

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

        print("DOT-SECTION", oinf.to_dot())
    """
    from skl2onnx.algebra.onnx_ops import (OnnxSub, OnnxReduceSumSquare,
                                           OnnxMul, OnnxReduceSum, OnnxReshape)
    diff = OnnxSub('X1', 'X2', op_version=target_opset)
    if weight_name is None:
        res = OnnxMul(OnnxReduceSumSquare(diff, op_version=target_opset),
                      numpy.array([multiply * 0.5], dtype=numpy.float32),
                      op_version=target_opset)
        res2 = OnnxMul(diff,
                       numpy.array([-multiply], dtype=dtype),
                       op_version=target_opset,
                       output_names=['Y_grad'])
    else:
        resh = OnnxReshape(weight_name,
                           numpy.array([-1, 1], dtype=numpy.int64),
                           op_version=target_opset)
        mul = OnnxMul(OnnxMul(diff, diff, op_version=target_opset),
                      resh,
                      op_version=target_opset)
        res = OnnxMul(OnnxReduceSum(mul, op_version=target_opset),
                      numpy.array([multiply * 0.5], dtype=numpy.float32),
                      op_version=target_opset)

        res2 = OnnxMul(OnnxMul(diff,
                               numpy.array([-multiply], dtype=dtype),
                               op_version=target_opset),
                       resh,
                       op_version=target_opset,
                       output_names=['Y_grad'])

    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()), ('Y_grad', var_type())],
                      target_opset=target_opset,
                      other_outputs=[res2])
    if weight_name is not None:
        onx = add_initializer(onx, weight_name, numpy.array([1], dtype=dtype))
    return onx
Example #11
0
 def get_onnx_mul(self):
     mul = OnnxMul('X', 'X', output_names=[
                   'Y'], op_version=get_opset_number_from_onnx())
     onx = mul.to_onnx(inputs=[('X', FloatTensorType())])
     return onx.SerializeToString()