mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #24039 from dkurt:tflite_test_backends
TFLite models on different backends (tests and improvements) #24039 ### Pull Request Readiness Checklist * MaxUnpooling with OpenVINO * Fully connected with transposed inputs/weights with OpenVINO * Enable backends tests for TFLite (related to https://github.com/opencv/opencv/issues/23992#issuecomment-1640691722) * Increase existing tests thresholds See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -180,15 +180,12 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
bool tranAorB = transA || transB;
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
return axis == 1 && !tranAorB;
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 && !tranAorB) ||
|
||||
(backendId == DNN_BACKEND_WEBNN && axis == 1 && !tranAorB) ||
|
||||
backendId == DNN_BACKEND_CANN ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() && !tranAorB);
|
||||
}
|
||||
|
||||
@@ -802,17 +799,26 @@ public:
|
||||
if (nodes.size() == 2)
|
||||
{
|
||||
auto& inp2 = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
matmul = std::make_shared<ngraph::op::MatMul>(ieInpNode, inp2, false, false);
|
||||
matmul = std::make_shared<ngraph::op::MatMul>(ieInpNode, inp2, transA, transB);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<int64_t> data = {(int64_t)ieInpNode->get_shape()[0], (int64_t)blobs[0].size[1]};
|
||||
auto new_shape = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, data.data());
|
||||
auto inp = std::make_shared<ngraph::op::v1::Reshape>(ieInpNode, new_shape, true);
|
||||
std::vector<int> shape(1 + normalize_axis(axis, ieInpNode->get_shape().size()), 0);
|
||||
shape[shape.size() - 1] = -1;
|
||||
auto inp = std::make_shared<ngraph::op::v1::Reshape>(
|
||||
ieInpNode,
|
||||
std::make_shared<ngraph::op::Constant>(ngraph::element::i32, ngraph::Shape{shape.size()}, shape.data()),
|
||||
true
|
||||
);
|
||||
|
||||
std::vector<size_t> weight_shape{(size_t)blobs[0].size[0], (size_t)blobs[0].size[1]};
|
||||
std::vector<size_t> weight_shape;
|
||||
if (isMatMul) {
|
||||
weight_shape = getShape<size_t>(oriMat);
|
||||
} else {
|
||||
weight_shape = {(size_t)blobs[0].size[0], (size_t)blobs[0].size[1]};
|
||||
}
|
||||
auto ieWeights = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, weight_shape, blobs[0].data);
|
||||
matmul = std::make_shared<ngraph::op::MatMul>(inp, ieWeights, false, true);
|
||||
matmul = std::make_shared<ngraph::op::MatMul>(inp, ieWeights, transA, transB);
|
||||
}
|
||||
|
||||
if (bias) {
|
||||
|
||||
@@ -13,6 +13,7 @@ Implementation of Batch Normalization layer.
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
@@ -41,6 +42,7 @@ public:
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && !poolPad.width && !poolPad.height);
|
||||
}
|
||||
|
||||
@@ -181,6 +183,50 @@ public:
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
auto features = nodes[0].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
auto indices = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
|
||||
|
||||
std::vector<MatShape> inpShapes(nodes.size());
|
||||
std::vector<MatShape> outShapes, internals;
|
||||
for (int i = 0; i < nodes.size(); ++i) {
|
||||
std::vector<size_t> shape = nodes[i].dynamicCast<InfEngineNgraphNode>()->node->get_shape();
|
||||
inpShapes[i] = std::vector<int>(shape.begin(), shape.end());
|
||||
}
|
||||
getMemoryShapes(inpShapes, 1, outShapes, internals);
|
||||
|
||||
Mat zeros = Mat::zeros(1, total(outShapes[0]), CV_32F);
|
||||
auto zeroInp = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{zeros.total()}, zeros.data);
|
||||
|
||||
int newShape = -1;
|
||||
features = std::make_shared<ngraph::op::v1::Reshape>(
|
||||
features,
|
||||
std::make_shared<ngraph::op::Constant>(ngraph::element::i32, ngraph::Shape{1}, &newShape),
|
||||
true
|
||||
);
|
||||
indices = std::make_shared<ngraph::op::v1::Reshape>(
|
||||
indices,
|
||||
std::make_shared<ngraph::op::Constant>(ngraph::element::i32, ngraph::Shape{1}, &newShape),
|
||||
true
|
||||
);
|
||||
if (indices->get_element_type() != ngraph::element::i32 && indices->get_element_type() != ngraph::element::i64) {
|
||||
indices = std::make_shared<ngraph::op::Convert>(indices, ngraph::element::i64);
|
||||
}
|
||||
|
||||
int axis = 0;
|
||||
std::shared_ptr<ngraph::Node> unpool = std::make_shared<ngraph::op::ScatterElementsUpdate>(zeroInp, indices, features,
|
||||
std::make_shared<ngraph::op::Constant>(ngraph::element::i32, ngraph::Shape{1}, &axis));
|
||||
|
||||
auto shape = std::make_shared<ngraph::op::Constant>(ngraph::element::i32, ngraph::Shape{outShapes[0].size()}, outShapes[0].data());
|
||||
unpool = std::make_shared<ngraph::op::v1::Reshape>(unpool, shape, true);
|
||||
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(unpool));
|
||||
}
|
||||
#endif // HAVE_DNN_NGRAPH
|
||||
};
|
||||
|
||||
Ptr<MaxUnpoolLayer> MaxUnpoolLayer::create(const LayerParams& params)
|
||||
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
return !computeMaxIdx && type != STOCHASTIC && kernel_size.size() > 1 && (kernel_size.size() != 3 || !isArmComputePlugin());
|
||||
return type != STOCHASTIC && kernel_size.size() > 1 && (kernel_size.size() != 3 || !isArmComputePlugin());
|
||||
}
|
||||
#endif
|
||||
if (backendId == DNN_BACKEND_OPENCV)
|
||||
@@ -613,9 +613,17 @@ public:
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(reduce_sum));
|
||||
}
|
||||
else if (type == MAX) {
|
||||
auto max_pool = std::make_shared<ngraph::op::v1::MaxPool>(ieInpNode, ngraph::Strides(strides),
|
||||
ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size),
|
||||
rounding_type, pad_type);
|
||||
std::shared_ptr<ngraph::Node> max_pool;
|
||||
if (computeMaxIdx) {
|
||||
std::vector<size_t> dilations(kernel_size.size(), 1);
|
||||
max_pool = std::make_shared<ngraph::op::v8::MaxPool>(ieInpNode, ngraph::Strides(strides), ngraph::Strides(dilations),
|
||||
ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size),
|
||||
rounding_type, pad_type);
|
||||
} else {
|
||||
max_pool = std::make_shared<ngraph::op::v1::MaxPool>(ieInpNode, ngraph::Strides(strides),
|
||||
ngraph::Shape(pads_begin), ngraph::Shape(pads_end), ngraph::Shape(kernel_size),
|
||||
rounding_type, pad_type);
|
||||
}
|
||||
return Ptr<BackendNode>(new InfEngineNgraphNode(max_pool));
|
||||
}
|
||||
else if (type == ROI) {
|
||||
|
||||
@@ -410,7 +410,10 @@ public:
|
||||
}
|
||||
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES;
|
||||
|
||||
if (alignCorners) {
|
||||
CV_Assert(!halfPixelCenters || !alignCorners);
|
||||
if (halfPixelCenters) {
|
||||
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL;
|
||||
} else if (alignCorners) {
|
||||
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS;
|
||||
}
|
||||
|
||||
@@ -427,7 +430,10 @@ public:
|
||||
}
|
||||
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
|
||||
|
||||
if (alignCorners) {
|
||||
CV_Assert(!halfPixelCenters || !alignCorners);
|
||||
if (halfPixelCenters) {
|
||||
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel;
|
||||
} else if (alignCorners) {
|
||||
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user