Skip to content

Instantly share code, notes, and snippets.

@l-bat
Created April 16, 2020 08:58
Show Gist options
  • Select an option

  • Save l-bat/927f961a95e1bbd58889d818fbe00309 to your computer and use it in GitHub Desktop.

Select an option

Save l-bat/927f961a95e1bbd58889d818fbe00309 to your computer and use it in GitHub Desktop.
#ifdef HAVE_DNN_NGRAPH
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> > &inputs,
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
{
auto& input = nodes[0].dynamicCast<InfEngineNgraphNode>()->node;
auto parent_shape = input->get_shape();
std::cout << "parent_shape " << parent_shape << std::endl;
std::vector<int> shape_vec(parent_shape.begin(), parent_shape.end());
int cols = shape_vec[1] * shape_vec[2] * anchors;
int rows = std::accumulate(shape_vec.begin(), shape_vec.end(), 1, std::multiplies<int>()) / cols;
// std::vector<int64_t> new_shape = {cols, rows};
std::vector<int64_t> new_shape = {rows, cols};
auto shape = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{new_shape.size()}, new_shape.data());
auto input2d = std::make_shared<ngraph::op::v1::Reshape>(input, shape, true);
std::cout << "input2d " << input2d->get_shape() << std::endl;
// srcData[bbox_index]
auto lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{0, 0});
auto upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, cols});
auto strides = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, 1});
auto box_x = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
std::cout << "slice " << box_x->get_shape() << std::endl;
auto logistic_x = std::make_shared<ngraph::op::Sigmoid>(box_x);
std::vector<int64_t> shape_add = {anchors, shape_vec[1], shape_vec[2]};
auto shape_add_node = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{shape_add.size()}, shape_add.data());
auto box_x_add = std::make_shared<ngraph::op::v1::Reshape>(logistic_x, shape_add_node, true);
std::vector<float> x_indices(shape_vec[2]);
std::iota(x_indices.begin(), x_indices.begin(), 0);
std::vector<size_t> horiz_shape(shape_add.size(), 1);
horiz_shape[2] = x_indices.size();
auto horiz = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape(horiz_shape), x_indices.data());
auto sum = std::make_shared<ngraph::op::v1::Add>(box_x_add, horiz, ngraph::op::AutoBroadcastType::NUMPY);
auto cols_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &shape_vec[2]);
auto box_x_final = std::make_shared<ngraph::op::v1::Divide>(sum, cols_node, ngraph::op::AutoBroadcastType::NUMPY);
std::cout << "box_x_final " << box_x_final->get_shape() << std::endl;
// srcData[box_index + 1]
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{1, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, cols});
auto box_y = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
std::cout << "slice " << box_y->get_shape() << std::endl;
auto logistic_y = std::make_shared<ngraph::op::Sigmoid>(box_y);
auto box_y_add = std::make_shared<ngraph::op::v1::Reshape>(logistic_y, shape_add_node, true);
std::vector<float> y_indices = x_indices;
std::vector<size_t> vert_shape(shape_add.size(), 1);
horiz_shape[1] = y_indices.size();
auto vert = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape(vert_shape), y_indices.data());
auto sum_y = std::make_shared<ngraph::op::v1::Add>(box_y_add, vert, ngraph::op::AutoBroadcastType::NUMPY);
auto rows_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, &shape_vec[1]);
auto box_y_final = std::make_shared<ngraph::op::v1::Divide>(sum_y, rows_node, ngraph::op::AutoBroadcastType::NUMPY);
std::cout << "box_y_final " << box_y_final->get_shape() << std::endl;
// bbox
int hNorm, wNorm;
if (nodes.size() > 1)
{
auto node_1_shape = nodes[1].dynamicCast<InfEngineNgraphNode>()->node->get_shape();
hNorm = node_1_shape[2];
wNorm = node_1_shape[3];
}
else
{
hNorm = shape_vec[1];
wNorm = shape_vec[2];
}
std::vector<float> anchors_w(anchors), anchors_h(anchors);
for (size_t i = 0; i < anchors; ++i)
{
anchors_w[i] = blobs[0].at<float>(0, 2 * i) / wNorm;
anchors_h[i] = blobs[0].at<float>(0, 2 * i + 1) / hNorm;
}
// bbox w
// dstData[box_index + 2] = exp(srcData[box_index + 2]) * biasData[2 * a] / wNorm;
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{2, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, cols});
auto box_w = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
auto exp_node = std::make_shared<ngraph::op::v0::Exp>(box_w);
auto box_w_3d = std::make_shared<ngraph::op::v1::Reshape>(exp_node, shape_add_node, true);
std::vector<size_t> box_w_shape(shape_add.size(), 1);
box_w_shape[0] = anchors_w.size();
auto anchor_w_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape(box_w_shape), anchors_w.data());
auto mul_w = std::make_shared<ngraph::op::v1::Multiply>(box_w_3d, anchor_w_node, ngraph::op::AutoBroadcastType::NUMPY);
std::cout << "mul_w " << mul_w->get_shape() << std::endl;
// bbox h
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{3, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, cols});
auto box_h = std::make_shared<ngraph::op::v1::StridedSlice>(input2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
auto exp_h_node = std::make_shared<ngraph::op::v0::Exp>(box_h);
auto box_h_3d = std::make_shared<ngraph::op::v1::Reshape>(exp_h_node, shape_add_node, true);
std::vector<size_t> box_h_shape(shape_add.size(), 1);
box_h_shape[0] = anchors_h.size();
auto anchor_h_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape(box_h_shape), anchors_h.data());
auto mul_h = std::make_shared<ngraph::op::v1::Multiply>(box_h_3d, anchor_h_node, ngraph::op::AutoBroadcastType::NUMPY);
std::cout << "mul_h " << mul_h->get_shape() << std::endl;
// calculate dstData
std::vector<float> anchors_vec(blobs[0].ptr<float>(), blobs[0].ptr<float>() + blobs[0].total());
std::vector<int64_t> mask(anchors_vec.size() / 2, 1);
int axis = 1;
int end_axis = 3;
auto region = std::make_shared<ngraph::op::RegionYolo>(input, coords, classes, anchors, useSoftmax, mask, axis, end_axis, anchors_vec);
std::cout << "region " << region->get_shape() << std::endl;
std::shared_ptr<ngraph::Node> region2d = std::make_shared<ngraph::op::v1::Reshape>(region, shape, true);
std::cout << "region2d " << region2d->get_shape() << std::endl;
// if (!useSoftmax && useLogistic)
// {
// region2d = std::make_shared<ngraph::op::Sigmoid>(region2d);
// }
// scale
// float scale = dstData[p_index];
// if (classfix == -1 && scale < .5) scale = 0; // if(t0 < 0.5) t0 = 0;
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{4, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, cols});
std::shared_ptr<ngraph::Node> scale_node = std::make_shared<ngraph::op::v1::StridedSlice>(region2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
if (classfix == -1)
{
auto thresh_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{1}, std::vector<float>(1, 0.5));
auto mask = std::make_shared<ngraph::op::v1::Less>(scale_node, thresh_node);
int count_elems = std::accumulate(mask->get_shape().begin(), mask->get_shape().end(), 1, std::multiplies<int>());
auto zero_node = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape(mask->get_shape()), std::vector<float>(count_elems, 0));
scale_node = std::make_shared<ngraph::op::v1::Select>(mask, scale_node, zero_node);
}
std::cout << "scale_node " << scale_node->get_shape() << std::endl;
// class probability
lower_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{5, 0});
upper_bounds = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, std::vector<int64_t>{rows, cols});
auto classes = std::make_shared<ngraph::op::v1::StridedSlice>(region2d, lower_bounds, upper_bounds, strides, std::vector<int64_t>{}, std::vector<int64_t>{});
std::cout << "classes " << classes->get_shape() << std::endl;
auto probs = std::make_shared<ngraph::op::v1::Multiply>(classes, scale_node, ngraph::op::AutoBroadcastType::NUMPY);
//concat box.x box.y box.w box.h scale probs
std::vector<int64_t> final_shape = {1, cols};
auto final_shape_node = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{final_shape.size()}, final_shape.data());
auto box_logit_x = std::make_shared<ngraph::op::v1::Reshape>(box_x_final, final_shape_node, true);
auto box_logit_y = std::make_shared<ngraph::op::v1::Reshape>(box_y_final, final_shape_node, true);
auto box_exp_w = std::make_shared<ngraph::op::v1::Reshape>(mul_w, final_shape_node, true);
auto box_exp_h = std::make_shared<ngraph::op::v1::Reshape>(mul_h, final_shape_node, true);
ngraph::NodeVector inp_nodes{box_logit_x, box_logit_y, box_exp_w, box_exp_h, scale_node, probs};
auto concat = std::make_shared<ngraph::op::Concat>(inp_nodes, 0);
auto tr_axes = std::make_shared<ngraph::op::Constant>(ngraph::element::i64,
ngraph::Shape{2}, std::vector<int64_t>{1, 0});
auto transpose = std::make_shared<ngraph::op::Transpose>(concat, tr_axes);
std::cout << "transpose " << transpose->get_shape() << std::endl;
// int class_index = index_sample_offset + index * cell_size + 5;
// for (int j = 0; j < classes; ++j) {
// float prob = scale*dstData[class_index + j]; // prob = IoU(box, object) = t0 * class-probability
// dstData[class_index + j] = (prob > thresh) ? prob : 0; // if (IoU < threshold) IoU = 0;
// }
// std::cout << "blobs[0] " << blobs[0].size << std::endl;
// auto shape = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{parent_shape.size()}, parent_shape.data());
// auto reshape = std::make_shared<ngraph::op::v1::Reshape>(region, shape, true);
// std::cout << "reshape " << reshape->get_shape() << std::endl;
// if (nmsThreshold > 0) {
// std::vector<ngraph::Output<ngraph::Node>> new_inputs{inputs.begin(), inputs.end()};
// if (new_inputs.size() == 2)
// new_inputs.push_back(ngraph::op::Constant::create(ngraph::element::i64, ngraph::Shape{}, {0}));
// for (size_t ind = new_inputs.size(); ind < 5; ++ind)
// new_inputs.push_back(ngraph::op::Constant::create(ngraph::element::f32, ngraph::Shape{}, {.0f}));
// // ngraph::op::v1::NonMaxSuppression::BoxEncodingType box_enc_type;
// // if (box_encoding_string == "corner") {
// // box_enc_type = ngraph::op::v1::NonMaxSuppression::BoxEncodingType::CORNER;
// // } else if (box_encoding_string == "center") {
// // box_enc_type = ngraph::op::v1::NonMaxSuppression::BoxEncodingType::CENTER;
// // }
// for (int b = 0; b < batch_size; ++b){
// do_nms_sort(dstData+b*sample_size, rows*cols*anchors, thresh, nmsThreshold);
// auto iou_threshold = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{}, {thresh});
// auto score_threshold = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{}, {nmsThreshold});
// std::make_shared<ngraph::op::v1::NonMaxSuppression>(new_inputs[0], new_inputs[1], new_inputs[2], iou_threshold, score_threshold);
// }
// }
return Ptr<BackendNode>(new InfEngineNgraphNode(transpose));
}
#endif // HAVE_DNN_NGRAPH
@l-bat
Copy link
Author

l-bat commented Apr 17, 2020

  // NMS return out with shape = {anchors*h*w x 3} 
        // std::vector<int64_t> boxes_shape{1, cols, 1};
        // auto boxes_shape_node = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{boxes_shape.size()}, boxes_shape.data());
        // box_x = std::make_shared<ngraph::op::v1::Reshape>(box_x, boxes_shape_node, true);
        // box_y = std::make_shared<ngraph::op::v1::Reshape>(box_y, boxes_shape_node, true);
        // box_w = std::make_shared<ngraph::op::v1::Reshape>(box_w, boxes_shape_node, true);
        // box_h = std::make_shared<ngraph::op::v1::Reshape>(box_h, boxes_shape_node, true);
        // auto boxes = std::make_shared<ngraph::op::Concat>(ngraph::NodeVector{box_x, box_y, box_w, box_h}, 2);

        // std::vector<int64_t> probs_shape{1, classes, cols};
        // auto probs_shape_node = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{probs_shape.size()}, probs_shape.data());
        // probs = std::make_shared<ngraph::op::v1::Reshape>(probs, probs_shape_node, true);

        // auto iou_threshold = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{}, &thresh);
        // auto score_threshold = std::make_shared<ngraph::op::Constant>(ngraph::element::f32, ngraph::Shape{}, &nmsThreshold);

        // auto max_output_boxes_per_class = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{}, std::vector<int64_t>{100});
        // auto nms_node = std::make_shared<ngraph::op::v1::NonMaxSuppression>(boxes, probs, max_output_boxes_per_class, iou_threshold, score_threshold);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment