mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #23319 from fengyuentau:fix_zoo_issue_136
Related issue: https://github.com/opencv/opencv_zoo/issues/136 Features added: - Support operators with multiple output: ONNX Split. - Support Slice without steps. Bugs fixed: - Wrong settings in ClipByValue (Relu6). - Wrong calculation of pads in convolution layer (It is wrong generally but only fixed specifically for CANN for now). ### Pull Request Readiness Checklist 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:
@@ -782,7 +782,8 @@ public:
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputsWrapper, const int index, const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputsWrapper,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
CV_Assert(!blobs.empty());
|
||||
CV_Assert(inputsWrapper.size() == 1);
|
||||
@@ -791,18 +792,35 @@ public:
|
||||
bool has_bias = hasBias() || fusedBias;
|
||||
|
||||
auto x = inputsWrapper[0].dynamicCast<CannBackendWrapper>();
|
||||
const int x_in_channel = x->host->size[1];
|
||||
const auto shape_x = x->host->size; // [b, c, h, w]
|
||||
const int filter_out_channel = blobs[0].size[1];
|
||||
const int groups = x_in_channel / filter_out_channel;
|
||||
const int groups = shape_x[1] / filter_out_channel;
|
||||
|
||||
// create operator
|
||||
std::string op_name = cv::format("conv2d_%d", index);
|
||||
auto op = std::make_shared<ge::op::Conv2D>(op_name);
|
||||
auto op = std::make_shared<ge::op::Conv2D>(name);
|
||||
|
||||
// set attributes
|
||||
op->set_attr_strides(ge::Operator::OpListInt(
|
||||
{1, 1, (int64_t)strides[0], (int64_t)strides[1]}
|
||||
));
|
||||
// recalculate pads in case of "SAME" padMode with odd pads
|
||||
// since in 'getConvPoolPaddings' pads are divided equally
|
||||
// leading to the loss of one pad
|
||||
if (padMode == "SAME")
|
||||
{
|
||||
for (int i = 0; i < pads_begin.size(); i++) {
|
||||
if (strides[i] <= kernel_size[i])
|
||||
{
|
||||
int pads_at_i = kernel_size[i] - 1 - (shape_x[i+2] - 1 + strides[i]) % strides[i];
|
||||
pads_begin[i] = pads_at_i / 2;
|
||||
// if odd, add extra padding to the end for SAME_UPPER
|
||||
// or to the beginning for SAME_LOWER. Since here we cannot
|
||||
// identity SAME_UPPER and SAME_LOWER, extra padding is always
|
||||
// added to the end.
|
||||
pads_end[i] = pads_at_i - pads_begin[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
op->set_attr_pads(ge::Operator::OpListInt(
|
||||
{(int64_t)pads_begin[1], (int64_t)pads_end[1], (int64_t)pads_begin[0], (int64_t)pads_end[0]}
|
||||
));
|
||||
@@ -815,12 +833,12 @@ public:
|
||||
// set inputs
|
||||
// set inputs : x
|
||||
auto op_x = nodes[0].dynamicCast<CannBackendNode>()->getOp();
|
||||
op->set_input_x_by_name(*op_x, "y");
|
||||
op->set_input_x_by_name(*op_x, x->name.c_str());
|
||||
auto x_desc = x->getTensorDesc();
|
||||
op->update_input_desc_x(*x_desc);
|
||||
// set inputs : weight
|
||||
const Mat& w_mat = blobs[0];
|
||||
auto op_const_weight = std::make_shared<CannConstOp>(w_mat.data, w_mat.type(), shape(w_mat), cv::format("%s_w", op_name.c_str()));
|
||||
auto op_const_weight = std::make_shared<CannConstOp>(w_mat.data, w_mat.type(), shape(w_mat), cv::format("%s_w", name.c_str()));
|
||||
op->set_input_filter(*(op_const_weight->getOp()));
|
||||
op->update_input_desc_filter(*(op_const_weight->getTensorDesc()));
|
||||
// set inputs : bias
|
||||
@@ -830,7 +848,7 @@ public:
|
||||
Mat b_mat({out_channel}, CV_32F, &biasvec[0]);
|
||||
|
||||
std::vector<int> bias_shape{out_channel};
|
||||
auto op_const_bias = std::make_shared<CannConstOp>(b_mat.data, b_mat.type(), bias_shape, cv::format("%s_b", op_name.c_str()));
|
||||
auto op_const_bias = std::make_shared<CannConstOp>(b_mat.data, b_mat.type(), bias_shape, cv::format("%s_b", name.c_str()));
|
||||
op->set_input_bias(*(op_const_bias->getOp()));
|
||||
op->update_input_desc_bias(*(op_const_bias->getTensorDesc()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user