示例#1
0
    def test_onnx_example_cdist_in_minkowski(self):
        x = numpy.array([1, 2, 1, 3, 2, 2, 2,
                         3]).astype(numpy.float32).reshape((4, 2))
        x2 = numpy.array([[1, 2], [2, 2], [2.1, 2.1],
                          [2, 2]]).astype(numpy.float32).reshape((4, 2))
        for pp in [1, 2]:
            with self.subTest(pp=pp):
                cop = OnnxIdentity('input',
                                   op_version=get_opset_number_from_onnx())
                cop2 = OnnxIdentity(onnx_cdist(
                    cop,
                    x2,
                    dtype=numpy.float32,
                    metric="minkowski",
                    p=pp,
                    op_version=get_opset_number_from_onnx()),
                                    output_names=['cdist'],
                                    op_version=get_opset_number_from_onnx())

                model_def = cop2.to_onnx(inputs=[('input',
                                                  FloatTensorType([None,
                                                                   None]))],
                                         outputs=[('cdist', FloatTensorType())
                                                  ])

                try:
                    sess = OnnxInference(model_def)
                except RuntimeError as e:
                    raise AssertionError("Issue\n{}".format(model_def)) from e
                res = sess.run({'input': x})['cdist']
                exp = scipy_cdist(x, x2, metric="minkowski", p=pp)
                self.assertEqualArray(exp, res, decimal=5)

        with self.subTest(pp=3):
            x = numpy.array([[6.1, 2.8, 4.7, 1.2], [5.7, 3.8, 1.7, 0.3],
                             [7.7, 2.6, 6.9, 2.3], [6.0, 2.9, 4.5, 1.5],
                             [6.8, 2.8, 4.8, 1.4], [5.4, 3.4, 1.5, 0.4],
                             [5.6, 2.9, 3.6, 1.3], [6.9, 3.1, 5.1, 2.3]],
                            dtype=numpy.float32)
            cop = OnnxAdd('input',
                          'input',
                          op_version=get_opset_number_from_onnx())
            cop2 = OnnxIdentity(onnx_cdist(
                cop,
                x,
                dtype=numpy.float32,
                metric="minkowski",
                p=3,
                op_version=get_opset_number_from_onnx()),
                                output_names=['cdist'],
                                op_version=get_opset_number_from_onnx())

            model_def = cop2.to_onnx(inputs=[('input',
                                              FloatTensorType([None, None]))],
                                     outputs=[('cdist', FloatTensorType())])

            sess = OnnxInference(model_def)
            res = sess.run({'input': x})['cdist']
            exp = scipy_cdist(x * 2, x, metric="minkowski", p=3)
            self.assertEqualArray(exp, res, decimal=4)
    def test_onnx_example_cdist_in(self):
        x = np.array([1, 2, 4, 5, 5, 4]).astype(np.float32).reshape((3, 2))
        x2 = np.array([1.1, 2.1, 4.01, 5.01, 5.001, 4.001, 0,
                       0]).astype(np.float32).reshape((4, 2))
        cop = OnnxAdd('input', 'input')
        cop2 = OnnxIdentity(onnx_cdist(cop, x2, dtype=np.float32),
                            output_names=['cdist'])

        model_def = cop2.to_onnx(inputs=[('input',
                                          FloatTensorType([None, None]))],
                                 outputs=[('cdist', FloatTensorType())])

        sess = InferenceSession(model_def.SerializeToString())
        res = sess.run(None, {'input': x})
        exp = scipy_cdist(x * 2, x2, metric="sqeuclidean")
        assert_almost_equal(exp, res[0], decimal=5)

        x = np.array(
            [[6.1, 2.8, 4.7, 1.2], [5.7, 3.8, 1.7, 0.3], [7.7, 2.6, 6.9, 2.3],
             [6.0, 2.9, 4.5, 1.5], [6.8, 2.8, 4.8, 1.4], [5.4, 3.4, 1.5, 0.4],
             [5.6, 2.9, 3.6, 1.3], [6.9, 3.1, 5.1, 2.3]],
            dtype=np.float32)
        cop = OnnxAdd('input', 'input')
        cop2 = OnnxIdentity(onnx_cdist(cop, x, dtype=np.float32),
                            output_names=['cdist'])

        model_def = cop2.to_onnx(inputs=[('input',
                                          FloatTensorType([None, None]))],
                                 outputs=[('cdist', FloatTensorType())])

        sess = InferenceSession(model_def.SerializeToString())
        res = sess.run(None, {'input': x})
        exp = scipy_cdist(x * 2, x, metric="sqeuclidean")
        assert_almost_equal(exp, res[0], decimal=4)
示例#3
0
def convert_score_cdist_sum(scope, operator, container):
    """
    Converts function @see fn score_cdist_sum into :epkg:`ONNX`.
    """
    op = operator.raw_operator
    if op._fct != score_cdist_sum:  # pylint: disable=W0143
        raise RuntimeError(  # pragma: no cover
            "The wrong converter was called {} != {}.".format(
                op._fct, score_cdist_sum))

    from skl2onnx.algebra.complex_functions import onnx_cdist
    from skl2onnx.algebra.onnx_ops import OnnxReduceSumApi11  # pylint: disable=E0611
    from skl2onnx.common.data_types import guess_numpy_type

    X = operator.inputs[0]
    Y = operator.inputs[1]
    out = operator.outputs
    opv = container.target_opset
    dtype = guess_numpy_type(operator.inputs[0].type)
    out = operator.outputs

    options = container.get_options(score_cdist_sum, dict(cdist=None))

    kwargs = op.kwargs

    if options.get('cdist', None) == 'single-node':
        attrs = kwargs
        cdist_name = scope.get_unique_variable_name('cdist')
        container.add_node('CDist', [X.full_name, Y.full_name], cdist_name,
                           op_domain='mlprodict', name=scope.get_unique_operator_name('CDist'),
                           **attrs)
        if container.target_opset < 13:
            container.add_node('ReduceSum', [cdist_name], out[0].full_name,
                               axes=[1], keepdims=0,
                               name=scope.get_unique_operator_name('ReduceSum'))
        else:
            axis_name = scope.get_unique_variable_name('axis')
            container.add_initializer(
                axis_name, onnx_proto.TensorProto.INT64, [1], [1])  # pylint: disable=E1101
            container.add_node(
                'ReduceSum', [cdist_name, axis_name],
                out[0].full_name, keepdims=0,
                name=scope.get_unique_operator_name('ReduceSum'))
    else:
        metric = kwargs['metric']
        if metric == 'minkowski':
            dists = onnx_cdist(X, Y, dtype=dtype, op_version=opv,
                               metric=metric, p=kwargs.get('p', 2))
        else:
            dists = onnx_cdist(X, Y, dtype=dtype, op_version=opv,
                               metric=kwargs['metric'])

        res = OnnxReduceSumApi11(dists, axes=[1], keepdims=0,
                                 output_names=[out[0].full_name],
                                 op_version=opv)
        res.add_to(scope, container)
    def test_onnx_example_cdist_in(self):
        from skl2onnx.algebra.complex_functions import onnx_cdist
        x = numpy.array([1, 2, 4, 5, 5, 4]).astype(numpy.float32).reshape(
            (3, 2))
        x2 = numpy.array([1.1, 2.1, 4.01, 5.01, 5.001, 4.001, 0,
                          0]).astype(numpy.float32).reshape((4, 2))
        cop = OnnxAdd('input',
                      'input',
                      op_version=get_opset_number_from_onnx())
        cop2 = OnnxIdentity(onnx_cdist(
            cop,
            x2,
            dtype=numpy.float32,
            op_version=get_opset_number_from_onnx()),
                            output_names=['cdist'],
                            op_version=get_opset_number_from_onnx())

        model_def = cop2.to_onnx(inputs=[('input',
                                          FloatTensorType([None, None]))],
                                 outputs=[('cdist',
                                           FloatTensorType(None, None))],
                                 target_opset=get_opset_number_from_onnx())

        sess = OnnxInference(model_def)
        res = sess.run({'input': x})
        exp = scipy_cdist(x * 2, x2, metric="sqeuclidean")
        self.assertEqualArray(exp, res['cdist'], decimal=5)

        x = numpy.array(
            [[6.1, 2.8, 4.7, 1.2], [5.7, 3.8, 1.7, 0.3], [7.7, 2.6, 6.9, 2.3],
             [6., 2.9, 4.5, 1.5], [6.8, 2.8, 4.8, 1.4], [5.4, 3.4, 1.5, 0.4],
             [5.6, 2.9, 3.6, 1.3], [6.9, 3.1, 5.1, 2.3]],
            dtype=numpy.float32)
        cop = OnnxAdd('input',
                      'input',
                      op_version=get_opset_number_from_onnx())
        cop2 = OnnxIdentity(onnx_cdist(
            cop,
            x,
            dtype=numpy.float32,
            op_version=get_opset_number_from_onnx()),
                            output_names=['cdist'],
                            op_version=get_opset_number_from_onnx())

        model_def = cop2.to_onnx(inputs=[('input',
                                          FloatTensorType([None, None]))],
                                 outputs=[('cdist', FloatTensorType())],
                                 target_opset=get_opset_number_from_onnx())

        sess = OnnxInference(model_def)
        res = sess.run({'input': x})
        exp = scipy_cdist(x * 2, x, metric="sqeuclidean")
        self.assertEqualArray(exp, res['cdist'], decimal=4)
    def test_onnx_example_cdist_bigger(self):

        from skl2onnx.algebra.complex_functions import onnx_cdist
        data = load_iris()
        X, y = data.data, data.target
        self.assertNotEmpty(y)
        X_train = X[::2]
        # y_train = y[::2]
        X_test = X[1::2]
        # y_test = y[1::2]
        onx = OnnxIdentity(onnx_cdist(OnnxIdentity('X',
                                                   op_version=TARGET_OPSET),
                                      X_train.astype(numpy.float32),
                                      metric="euclidean",
                                      dtype=numpy.float32,
                                      op_version=TARGET_OPSET),
                           output_names=['Y'],
                           op_version=TARGET_OPSET)
        final = onx.to_onnx(inputs=[('X', FloatTensorType([None, None]))],
                            outputs=[('Y', FloatTensorType())],
                            target_opset=TARGET_OPSET)

        oinf = OnnxInference(final, runtime="python")
        res = oinf.run({'X': X_train.astype(numpy.float32)})['Y']
        exp = scipy_cdist(X_train, X_train, metric="euclidean")
        self.assertEqualArray(exp, res, decimal=6)
        res = oinf.run({'X': X_test.astype(numpy.float32)})['Y']
        exp = scipy_cdist(X_test, X_train, metric="euclidean")
        self.assertEqualArray(exp, res, decimal=6)
    def test_onnx_example_cdist_in_euclidean(self):
        x2 = numpy.array([1.1, 2.1, 4.01, 5.01, 5.001, 4.001, 0,
                          0]).astype(numpy.float32).reshape((4, 2))
        cop = OnnxAdd('input',
                      'input',
                      op_version=get_opset_number_from_onnx())
        cop2 = OnnxIdentity(onnx_cdist(
            cop,
            x2,
            dtype=numpy.float32,
            metric='euclidean',
            op_version=get_opset_number_from_onnx()),
                            output_names=['cdist'],
                            op_version=get_opset_number_from_onnx())

        model_def = cop2.to_onnx(inputs=[('input',
                                          FloatTensorType([None, None]))],
                                 outputs=[('cdist', FloatTensorType())],
                                 target_opset=get_opset_number_from_onnx())

        new_model = onnx_remove_node_identity(model_def)
        stats = onnx_statistics(model_def, optim=False)
        stats2 = onnx_statistics(new_model, optim=False)
        self.assertEqual(stats.get('op_Identity', 0), 3)
        self.assertEqual(stats2.get('op_Identity', 0), 1)
示例#7
0
    def test_onnx_example_cdist_in_euclidean(self):
        for metric in ['euclidean', 'minkowski']:
            for opv in [11, TARGET_OPSET]:
                with self.subTest(metric=metric, opv=opv):
                    x = numpy.array([1, 2, 4, 5, 5,
                                     4]).astype(numpy.float32).reshape((3, 2))
                    x2 = numpy.array(
                        [1.1, 2.1, 4.01, 5.01, 5.001, 4.001, 0,
                         0]).astype(numpy.float32).reshape((4, 2))
                    cop = OnnxAdd('input', 'input', op_version=opv)

                    if metric == "minkowski":
                        cop2 = OnnxIdentity(onnx_cdist(cop,
                                                       x2,
                                                       dtype=numpy.float32,
                                                       metric=metric,
                                                       op_version=opv,
                                                       p=2),
                                            output_names=['cdist'],
                                            op_version=opv)
                    else:
                        cop2 = OnnxIdentity(onnx_cdist(cop,
                                                       x2,
                                                       dtype=numpy.float32,
                                                       metric=metric,
                                                       op_version=opv),
                                            output_names=['cdist'],
                                            op_version=opv)

                    model_def = cop2.to_onnx(inputs=[
                        ('input', FloatTensorType([None, None]))
                    ],
                                             outputs=[('cdist',
                                                       FloatTensorType())],
                                             target_opset=opv)

                    sess = OnnxInference(model_def)
                    res = sess.run({'input': x})['cdist']
                    exp = scipy_cdist(x * 2, x2, metric=metric)
                    self.assertEqualArray(exp, res, decimal=5)

                    if metric == "minkowski":
                        continue
                    x = numpy.array(
                        [[6.1, 2.8, 4.7, 1.2], [5.7, 3.8, 1.7, 0.3],
                         [7.7, 2.6, 6.9, 2.3], [6.0, 2.9, 4.5, 1.5],
                         [6.8, 2.8, 4.8, 1.4], [5.4, 3.4, 1.5, 0.4],
                         [5.6, 2.9, 3.6, 1.3], [6.9, 3.1, 5.1, 2.3]],
                        dtype=numpy.float32)
                    cop = OnnxAdd('input', 'input', op_version=opv)
                    cop2 = OnnxIdentity(onnx_cdist(cop,
                                                   x,
                                                   dtype=numpy.float32,
                                                   op_version=opv),
                                        output_names=['cdist'],
                                        op_version=opv)

                    model_def = cop2.to_onnx(inputs=[
                        ('input', FloatTensorType([None, None]))
                    ],
                                             outputs=[('cdist',
                                                       FloatTensorType())],
                                             target_opset=opv)

                    sess = OnnxInference(model_def)
                    res = sess.run({'input': x})['cdist']
                    exp = scipy_cdist(x * 2, x, metric="sqeuclidean")
                    self.assertEqualArray(exp, res, decimal=4)