[Opset13][pyAPI] Python API Multinomial-13 (#20400)
* Init Multinomial op python API * Add python tests for Multinomial op * Update num_samples input description
This commit is contained in:
parent
e8d80f9b0d
commit
146b0c0be8
@ -106,6 +106,7 @@ from openvino.runtime.opset1.ops import minimum
|
|||||||
from openvino.runtime.opset4.ops import mish
|
from openvino.runtime.opset4.ops import mish
|
||||||
from openvino.runtime.opset1.ops import mod
|
from openvino.runtime.opset1.ops import mod
|
||||||
from openvino.runtime.opset9.ops import multiclass_nms
|
from openvino.runtime.opset9.ops import multiclass_nms
|
||||||
|
from openvino.runtime.opset13.ops import multinomial
|
||||||
from openvino.runtime.opset1.ops import multiply
|
from openvino.runtime.opset1.ops import multiply
|
||||||
from openvino.runtime.opset6.ops import mvn
|
from openvino.runtime.opset6.ops import mvn
|
||||||
from openvino.runtime.opset1.ops import negative
|
from openvino.runtime.opset1.ops import negative
|
||||||
|
@ -110,6 +110,47 @@ def bitwise_xor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@nameable_op
|
||||||
|
def multinomial(
|
||||||
|
probs: NodeInput,
|
||||||
|
num_samples: NodeInput,
|
||||||
|
convert_type: str,
|
||||||
|
with_replacement: bool,
|
||||||
|
log_probs: bool,
|
||||||
|
global_seed: int = 0,
|
||||||
|
op_seed: int = 0,
|
||||||
|
) -> Node:
|
||||||
|
"""Return a node which generates a sequence of class indices sampled from the multinomial distribution.
|
||||||
|
|
||||||
|
:param probs: Tensor with probabilities of floating-point type, and shape [class_size] or [batch_size, class_size].
|
||||||
|
:param num_samples: Tensor (scalar or 1D) a single element of type i32 or i64,
|
||||||
|
specifying the number of samples to draw from the multinomial distribution.
|
||||||
|
:param convert_type: Specifies the output tensor type, possible values: 'i64', 'i32'.
|
||||||
|
:param with_replacement: Flag that specifies whether to sample with replacement.
|
||||||
|
:param log_probs: Flag that specifies whether *probs* should be treated as unnormalized log probabilities.
|
||||||
|
:param global_seed: Specifies global seed value. Required to be a positive integer or 0.
|
||||||
|
:param op_seed: Specifies operational seed value. Required to be a positive integer or 0.
|
||||||
|
|
||||||
|
:return: The new node performing Multinomial operation.
|
||||||
|
"""
|
||||||
|
inputs = as_nodes(probs, num_samples)
|
||||||
|
|
||||||
|
if global_seed < 0:
|
||||||
|
raise RuntimeError(f"global_seed should be positive or 0. Got: {global_seed}")
|
||||||
|
|
||||||
|
if op_seed < 0:
|
||||||
|
raise RuntimeError(f"op_seed should be positive or 0. Got: {op_seed}")
|
||||||
|
|
||||||
|
attributes = {
|
||||||
|
"convert_type": convert_type,
|
||||||
|
"with_replacement": with_replacement,
|
||||||
|
"log_probs": log_probs,
|
||||||
|
"global_seed": global_seed,
|
||||||
|
"op_seed": op_seed,
|
||||||
|
}
|
||||||
|
return _get_node_factory_opset13().create("Multinomial", inputs, attributes)
|
||||||
|
|
||||||
|
|
||||||
@nameable_op
|
@nameable_op
|
||||||
def nms_rotated(
|
def nms_rotated(
|
||||||
boxes: NodeInput,
|
boxes: NodeInput,
|
||||||
|
78
src/bindings/python/tests/test_graph/test_multinomial.py
Normal file
78
src/bindings/python/tests/test_graph/test_multinomial.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2018-2023 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import openvino.runtime.opset13 as ops
|
||||||
|
from openvino.runtime import PartialShape, Dimension, Type
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("probs_shape", "num_samples_shape", "convert_type", "with_replacement", "log_probs", "global_seed", "op_seed", "expected_out_shape"),
|
||||||
|
[
|
||||||
|
([4, 16], [], "i32", False, True, 7461, 1546, PartialShape([4, -1])),
|
||||||
|
([8], [1], "i64", True, False, 0, 0, PartialShape([-1])),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_multinomial_param_inputs(probs_shape, num_samples_shape, convert_type, with_replacement, log_probs, global_seed, op_seed, expected_out_shape):
|
||||||
|
probs = ops.parameter(probs_shape, dtype=np.float32)
|
||||||
|
num_samples = ops.parameter(num_samples_shape, dtype=np.int32)
|
||||||
|
|
||||||
|
op = ops.multinomial(probs, num_samples,
|
||||||
|
convert_type=convert_type,
|
||||||
|
with_replacement=with_replacement,
|
||||||
|
log_probs=log_probs,
|
||||||
|
global_seed=global_seed,
|
||||||
|
op_seed=op_seed)
|
||||||
|
assert op.get_output_size() == 1
|
||||||
|
assert op.get_type_name() == "Multinomial"
|
||||||
|
assert op.get_output_element_type(0) == Type.i32 if convert_type == "i32" else Type.i64
|
||||||
|
assert op.get_output_partial_shape(0) == expected_out_shape
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("probs_array", "num_samples_val", "convert_type", "with_replacement", "log_probs", "global_seed", "op_seed", "expected_out_shape"),
|
||||||
|
[
|
||||||
|
(np.array([0.7, 0.3, 0.6, 0.5]), 3, "i32", False, True, 111, 222, PartialShape([3])),
|
||||||
|
(np.array([[0.7, 0.3], [0.6, 0.5]]), 2, "i64", True, False, 111, 222, PartialShape([2, 2])),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_multinomial_const_inputs(probs_array, num_samples_val, convert_type, with_replacement, log_probs, global_seed, op_seed, expected_out_shape):
|
||||||
|
probs = ops.constant(probs_array, dtype=np.float32)
|
||||||
|
num_samples = ops.constant(num_samples_val, dtype=np.int32)
|
||||||
|
|
||||||
|
op = ops.multinomial(probs, num_samples,
|
||||||
|
convert_type=convert_type,
|
||||||
|
with_replacement=with_replacement,
|
||||||
|
log_probs=log_probs,
|
||||||
|
global_seed=global_seed,
|
||||||
|
op_seed=op_seed)
|
||||||
|
|
||||||
|
assert op.get_output_size() == 1
|
||||||
|
assert op.get_type_name() == "Multinomial"
|
||||||
|
assert op.get_output_element_type(0) == Type.i32 if convert_type == "i32" else Type.i64
|
||||||
|
assert op.get_output_partial_shape(0) == expected_out_shape
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("probs_shape", "num_samples_shape", "convert_type", "with_replacement", "log_probs", "expected_out_shape"),
|
||||||
|
[
|
||||||
|
([10], [1], "i32", True, True, PartialShape([-1])),
|
||||||
|
([2, 16], [], "i64", False, False, PartialShape([2, -1])),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_multinomial_default_attrs(probs_shape, num_samples_shape, convert_type, with_replacement, log_probs, expected_out_shape):
|
||||||
|
probs = ops.parameter(probs_shape, dtype=np.float32)
|
||||||
|
num_samples = ops.parameter(num_samples_shape, dtype=np.int32)
|
||||||
|
|
||||||
|
op = ops.multinomial(probs, num_samples,
|
||||||
|
convert_type=convert_type,
|
||||||
|
with_replacement=with_replacement,
|
||||||
|
log_probs=log_probs)
|
||||||
|
|
||||||
|
assert op.get_output_size() == 1
|
||||||
|
assert op.get_type_name() == "Multinomial"
|
||||||
|
assert op.get_output_element_type(0) == Type.i32 if convert_type == "i32" else Type.i64
|
||||||
|
assert op.get_output_partial_shape(0) == expected_out_shape
|
Loading…
Reference in New Issue
Block a user