diff --git a/src/frontends/onnx/frontend/src/op/batch_norm.cpp b/src/frontends/onnx/frontend/src/op/batch_norm.cpp index 04a613bc10bdb7..fc4a3c2a4fd9d1 100644 --- a/src/frontends/onnx/frontend/src/op/batch_norm.cpp +++ b/src/frontends/onnx/frontend/src/op/batch_norm.cpp @@ -52,6 +52,12 @@ ov::OutputVector batch_norm(const ov::frontend::onnx::Node& node) { OPENVINO_THROW("Cannot create OpenVINO batch norm with unsupported number of inputs"); } } // namespace set_1 +/* + Opset 6 is skipped because there are no significant difference between opset1 and opset6. + Found difference is: + 1. In Training, the computation of ReduceMean and ReduceVar uses float + to avoid overflow for float16 inputs. + */ namespace set_7 { // This version supports ONNX BatchNormalization-7 and BatchNormalization-9 @@ -71,8 +77,42 @@ ov::OutputVector batch_norm(const ov::frontend::onnx::Node& node) { return {std::make_shared(x, scale, bias, mean, var, epsilon)}; } - } // namespace set_7 +/* + Opset 9 is skipped because there are no significant difference between opset7 and opset9. + Found difference is: + 1. removed -> spatial : int (default is 1) + If true, compute the mean and variance across per activation. If false, compute the mean and variance across + per feature over each mini-batch. + + */ + +namespace set_14 { +// This version supports ONNX BatchNormalization-14 BatchNormalization-15 +ov::OutputVector batch_norm(const ov::frontend::onnx::Node& node) { + ov::OutputVector inputs{node.get_ov_inputs()}; + auto x = inputs.at(0); + auto scale = inputs.at(1); + auto bias = inputs.at(2); + auto mean = inputs.at(3); + auto var = inputs.at(4); + + double epsilon{node.get_attribute_value("epsilon", 1e-5)}; + int64_t training_mode{node.get_attribute_value("training_mode", 0)}; + + CHECK_VALID_NODE(node, + training_mode == false && node.get_outputs_size() == 1, + "Training mode of BatchNormalization is not supported."); + return {std::make_shared(x, scale, bias, mean, var, epsilon)}; +} +} // namespace set_14 +/* + Opset 15 is skipped because there are no significant difference between opset14 and opset15. + Found difference is: + 1. In Training, the computation of ReduceMean and ReduceVar uses float + to avoid overflow for float16 inputs. + */ + } // namespace op } // namespace onnx } // namespace frontend diff --git a/src/frontends/onnx/frontend/src/op/batch_norm.hpp b/src/frontends/onnx/frontend/src/op/batch_norm.hpp index fbf4c715bb15de..29a79d444152d2 100644 --- a/src/frontends/onnx/frontend/src/op/batch_norm.hpp +++ b/src/frontends/onnx/frontend/src/op/batch_norm.hpp @@ -19,6 +19,11 @@ namespace set_7 { ov::OutputVector batch_norm(const ov::frontend::onnx::Node& node); } // namespace set_7 + +namespace set_14 { +ov::OutputVector batch_norm(const ov::frontend::onnx::Node& node); + +} // namespace set_14 } // namespace op } // namespace onnx } // namespace frontend diff --git a/src/frontends/onnx/frontend/src/ops_bridge.cpp b/src/frontends/onnx/frontend/src/ops_bridge.cpp index 0acbb0c9a8c2f4..02255b673ca576 100644 --- a/src/frontends/onnx/frontend/src/ops_bridge.cpp +++ b/src/frontends/onnx/frontend/src/ops_bridge.cpp @@ -360,6 +360,7 @@ OperatorsBridge::OperatorsBridge() { REGISTER_OPERATOR("AveragePool", 1, average_pool); REGISTER_OPERATOR("BatchNormalization", 1, batch_norm); REGISTER_OPERATOR("BatchNormalization", 7, batch_norm); + REGISTER_OPERATOR("BatchNormalization", 14, batch_norm); REGISTER_OPERATOR("BitShift", 1, bitshift); REGISTER_OPERATOR("BitwiseAnd", 1, bitwise_and); REGISTER_OPERATOR("BitwiseNot", 1, bitwise_not); diff --git a/src/frontends/onnx/tests/models/batchnorm_opset1.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset1.prototxt new file mode 100644 index 00000000000000..11bed1195afa2b --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset1.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 1 +} diff --git a/src/frontends/onnx/tests/models/batchnorm_opset14.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset14.prototxt new file mode 100644 index 00000000000000..48edc903669cc4 --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset14.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 14 +} diff --git a/src/frontends/onnx/tests/models/batchnorm_opset15.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset15.prototxt new file mode 100644 index 00000000000000..cf0a43fec08c0f --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset15.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 15 +} diff --git a/src/frontends/onnx/tests/models/batchnorm_opset6.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset6.prototxt new file mode 100644 index 00000000000000..31217f90df3b47 --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset6.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 6 +} diff --git a/src/frontends/onnx/tests/models/batchnorm_opset7.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset7.prototxt new file mode 100644 index 00000000000000..cdc60d2c2a038f --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset7.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 7 +} diff --git a/src/frontends/onnx/tests/models/batchnorm_opset9.prototxt b/src/frontends/onnx/tests/models/batchnorm_opset9.prototxt new file mode 100644 index 00000000000000..e7e7459f9d0d3b --- /dev/null +++ b/src/frontends/onnx/tests/models/batchnorm_opset9.prototxt @@ -0,0 +1,113 @@ +ir_version: 3 +producer_name: "OpenVINO ONNX Frontend" +graph { + node { + input: "x" + input: "s" + input: "bias" + input: "mean" + input: "var" + output: "y" + op_type: "BatchNormalization" + } + name: "test_batchnorm_example" + input { + name: "x" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } + input { + name: "s" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "bias" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "mean" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + input { + name: "var" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 2 + } + } + } + } + } + output { + name: "y" + type { + tensor_type { + elem_type: 1 + shape { + dim { + dim_value: 1 + } + dim { + dim_value: 2 + } + dim { + dim_value: 1 + } + dim { + dim_value: 3 + } + } + } + } + } +} +opset_import { + version: 9 +} diff --git a/src/frontends/onnx/tests/onnx_import.in.cpp b/src/frontends/onnx/tests/onnx_import.in.cpp index 74ace1949c8177..7b3e39e71399aa 100644 --- a/src/frontends/onnx/tests/onnx_import.in.cpp +++ b/src/frontends/onnx/tests/onnx_import.in.cpp @@ -320,6 +320,95 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_default) { test_case.run(); } +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset1) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset1.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} + +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset6) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset6.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} + +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset7) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset7.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset9) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset9.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} + +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset14) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset14.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} + +OPENVINO_TEST(${BACKEND_NAME}, onnx_model_batch_norm_opset15) { + // Batch Normalization with default parameters + auto model = convert_model("batchnorm_opset15.onnx"); + + auto test_case = ov::test::TestCase(model, s_device); + test_case.add_input({-1.f, 0.f, 1.f, 2.f, 3.f, 4.f}); // data {1, 2, 1, 3} + test_case.add_input({1.f, 1.5f}); // scale + test_case.add_input({0.f, 1.f}); // bias + test_case.add_input({0.f, 3.f}); // mean + test_case.add_input({1.f, 1.5f}); // var + test_case.add_expected_output(Shape{1, 2, 1, 3}, + {-0.999995f, 0.f, 0.999995f, -0.22474074f, 1.f, 2.2247407f}); + test_case.run(); +} + OPENVINO_TEST(${BACKEND_NAME}, onnx_model_relu) { // Simple ReLU test auto model = convert_model("relu.onnx");