Skip to content

Commit

Permalink
[FrontEnd]Paddle_Op_Conversion_prior_box (#7639)
Browse files Browse the repository at this point in the history
* Paddle_Op_Conversion_prior_box

* use default_opset

* apply review comments

* const type variables modification
  • Loading branch information
liubo-intel authored Oct 6, 2021
1 parent 5ef3472 commit f83cf4b
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 0 deletions.
112 changes: 112 additions & 0 deletions ngraph/frontend/paddlepaddle/src/op/prior_box.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "ngraph/op/prior_box.hpp"

#include <node_context.hpp>

#include "default_opset.hpp"

namespace ngraph {
namespace frontend {
namespace pdpd {
namespace op {
using namespace default_opset;
using namespace element;
namespace detail {
namespace {
std::shared_ptr<StridedSlice> make_slice(const std::shared_ptr<ngraph::Node>& node, int64_t start, int64_t end) {
return std::make_shared<StridedSlice>(node,
Constant::create(i64, Shape{1}, std::vector<int64_t>{start}),
Constant::create(i64, Shape{1}, std::vector<int64_t>{end}),
std::vector<int64_t>{0}, // begin mask
std::vector<int64_t>{0}); // end mask
}
} // namespace
} // namespace detail
NamedOutputs prior_box(const NodeContext& node) {
auto input = node.get_ng_input("Input");
auto Image = node.get_ng_input("Image");
const auto input_shape = std::make_shared<ShapeOf>(input);
const auto Image_shape = std::make_shared<ShapeOf>(Image);
const auto output_shape_slice = detail::make_slice(input_shape, 2, 4);
const auto image_shape_slice = detail::make_slice(Image_shape, 2, 4);

ngraph::op::PriorBoxAttrs attrs;
attrs.min_size = node.get_attribute<std::vector<float>>("min_sizes", {});
attrs.max_size = node.get_attribute<std::vector<float>>("max_sizes", {});
attrs.aspect_ratio = node.get_attribute<std::vector<float>>("aspect_ratios", {1.0});
attrs.flip = node.get_attribute<bool>("flip", false);
attrs.clip = node.get_attribute<bool>("clip", false);
attrs.step = node.get_attribute<float>("step_w", 0);

attrs.offset = node.get_attribute<float>("offset", 0.5);
attrs.variance = node.get_attribute<std::vector<float>>("variances", {0.1, 0.1, 0.2, 0.2});

bool min_max_aspect_ratios_order = node.get_attribute<bool>("min_max_aspect_ratios_order", false);

const auto ov_prior_box_node = std::make_shared<PriorBox>(output_shape_slice, image_shape_slice, attrs);

const auto split_axis_node = Constant::create(i64, ngraph::Shape{}, {0});
const auto node_prior_box_split = std::make_shared<Split>(ov_prior_box_node, split_axis_node, 2);

const auto node_boxes_origin = node_prior_box_split->output(0);
const auto node_variances_origin = node_prior_box_split->output(1);

const auto out_shape =
std::make_shared<Concat>(NodeVector{output_shape_slice, Constant::create<int64_t>(i64, {2}, {-1, 4})}, 0);

auto node_boxes_reshape = std::make_shared<Reshape>(node_boxes_origin, out_shape, true);
const auto node_variances_reshape = std::make_shared<Reshape>(node_variances_origin, out_shape, true);

int64_t total_aspect_ratios = ngraph::op::PriorBox::normalized_aspect_ratio(attrs.aspect_ratio, attrs.flip).size();
if ((total_aspect_ratios > 1) && !attrs.min_size.empty() && !attrs.max_size.empty() &&
!min_max_aspect_ratios_order) {
std::vector<int64_t> mask{1, 1, 1, 0, 1};
int64_t min_size_len = static_cast<int64_t>(attrs.min_size.size());

const auto out_shape_div_numpri = std::make_shared<Concat>(
NodeVector{output_shape_slice, Constant::create<int64_t>(i64, {3}, {min_size_len, -1, 4})},
0);
const auto node_boxes_div_numpri = std::make_shared<Reshape>(node_boxes_reshape, out_shape_div_numpri, true);

const auto slice_begin_min = Constant::create(i64, Shape{5}, std::vector<int64_t>{0, 0, 0, 0, 0});
const auto slice_end_min = std::make_shared<Concat>(
NodeVector{output_shape_slice, Constant::create<int64_t>(i64, {3}, {min_size_len, 1, 4})},
0);
const auto slice_min_node =
std::make_shared<StridedSlice>(node_boxes_div_numpri, slice_begin_min, slice_end_min, mask, mask);

const auto slice_begin_max = Constant::create(i64, Shape{5}, std::vector<int64_t>{0, 0, 0, 1, 0});
const auto slice_end_max = std::make_shared<Concat>(
NodeVector{output_shape_slice, Constant::create<int64_t>(i64, {3}, {min_size_len, 2, 4})},
0);
const auto slice_max_node =
std::make_shared<StridedSlice>(node_boxes_div_numpri, slice_begin_max, slice_end_max, mask, mask);

const auto slice_begin_aspect_ratios = Constant::create(i64, Shape{5}, std::vector<int64_t>{0, 0, 0, 2, 0});
const auto slice_end_aspect_ratios = std::make_shared<Concat>(
NodeVector{output_shape_slice,
Constant::create<int64_t>(i64, {3}, {min_size_len, 2 + (total_aspect_ratios - 1), 4})},
0);
const auto slice_aspect_ratios_node = std::make_shared<StridedSlice>(node_boxes_div_numpri,
slice_begin_aspect_ratios,
slice_end_aspect_ratios,
mask,
mask);

const auto node_boxes_div_numpri_reorder =
std::make_shared<Concat>(NodeVector{slice_min_node, slice_aspect_ratios_node, slice_max_node}, 3);
node_boxes_reshape = std::make_shared<Reshape>(node_boxes_div_numpri_reorder, out_shape, true);
}

NamedOutputs outputs;
outputs["Boxes"] = {node_boxes_reshape};
outputs["Variances"] = {node_variances_reshape};
return outputs;
}
} // namespace op
} // namespace pdpd
} // namespace frontend
} // namespace ngraph
2 changes: 2 additions & 0 deletions ngraph/frontend/paddlepaddle/src/op_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ OP_CONVERTER(nearest_interp_v2);
OP_CONVERTER(pad3d);
OP_CONVERTER(pow);
OP_CONVERTER(pool2d);
OP_CONVERTER(prior_box);
OP_CONVERTER(range);
OP_CONVERTER(relu);
OP_CONVERTER(relu6);
Expand Down Expand Up @@ -126,6 +127,7 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
{"pad3d", op::pad3d},
{"pow", op::pow},
{"pool2d", op::pool2d},
{"prior_box", op::prior_box},
{"range", op::range},
{"relu", op::relu},
{"relu6", op::relu6},
Expand Down
4 changes: 4 additions & 0 deletions ngraph/test/frontend/paddlepaddle/op_fuzzy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ static const std::vector<std::string> models{std::string("argmax"),
std::string("pow_int64"),
// pow_int64_out_of_range(out of range of OV int64),
std::string("pow_y_tensor"),
std::string("prior_box_attrs_mmar_order_true"),
std::string("prior_box_default"),
std::string("prior_box_flip_clip_false"),
std::string("prior_box_max_sizes_none"),
std::string("range0"),
std::string("range1"),
std::string("range2"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#
# prior_box paddle model generator
#
import numpy as np
from save_model import saveModel
import sys


def prior_box(name: str, input_data, image_data, attrs: dict):
import paddle as pdpd
pdpd.enable_static()

with pdpd.static.program_guard(pdpd.static.Program(), pdpd.static.Program()):
Input = pdpd.static.data(
name='Input', shape=input_data.shape, dtype=input_data.dtype)
Image = pdpd.static.data(
name='Image', shape=image_data.shape, dtype=image_data.dtype)

box, var = pdpd.fluid.layers.prior_box(Input,
Image,
min_sizes=attrs['min_sizes'],
max_sizes=attrs['max_sizes'],
aspect_ratios=attrs['aspect_ratios'],
variance=attrs['variance'],
flip=attrs['flip'],
clip=attrs['clip'],
steps=attrs['steps'],
offset=attrs['offset'],
name=None,
min_max_aspect_ratios_order=attrs['min_max_aspect_ratios_order'])

cpu = pdpd.static.cpu_places(1)
exe = pdpd.static.Executor(cpu[0])
# startup program will call initializer to initialize the parameters.
exe.run(pdpd.static.default_startup_program())

outs = exe.run(
feed={'Input': input_data, 'Image': image_data},
fetch_list=[box, var])

# Save inputs in order of ngraph function, to facilite Fuzzy test,
# which accepts inputs and outputs in this order as well.
saveModel(name, exe, feedkeys=['Input', 'Image'], fetchlist=[box, var],
inputs=[input_data, image_data], outputs=outs, target_dir=sys.argv[1])
return outs


if __name__ == "__main__":

prior_box_attrs_default = {
'name': "prior_box_default",
'min_sizes': np.array([2, 4]).astype('float32').tolist(),
'max_sizes': np.array([5, 10]).astype('float32').tolist(),
'aspect_ratios': [2.0, 3.0],
'flip': True,
'clip': True,
'steps': np.array([1.25, 1.25]).astype('float32').tolist(),
'offset': 0.5,
'variance': np.array([0.1, 0.1, 0.2, 0.2], dtype=np.float).flatten(),
'min_max_aspect_ratios_order': False
}

prior_box_max_sizes_none = {
'name': "prior_box_max_sizes_none",
'min_sizes': np.array([2, 4]).astype('float32').tolist(),
'max_sizes': None,
'aspect_ratios': [2.0, 3.0],
'flip': True,
'clip': True,
'steps': np.array([1.25, 1.25]).astype('float32').tolist(),
'offset': 0.5,
'variance': np.array([0.1, 0.1, 0.2, 0.2], dtype=np.float).flatten(),
'min_max_aspect_ratios_order': False
}

prior_box_flip_clip_false = {
'name': "prior_box_flip_clip_false",
'min_sizes': np.array([2, 4]).astype('float32').tolist(),
'max_sizes': np.array([5, 10]).astype('float32').tolist(),
'aspect_ratios': [2.0, 3.0],
'flip': False,
'clip': False,
'steps': np.array([1.25, 1.25]).astype('float32').tolist(),
'offset': 0.5,
'variance': np.array([0.1, 0.1, 0.2, 0.2], dtype=np.float).flatten(),
'min_max_aspect_ratios_order': False
}

prior_box_attrs_mmar_order_true = {
'name': "prior_box_attrs_mmar_order_true",
'min_sizes': np.array([2, 4]).astype('float32').tolist(),
'max_sizes': np.array([5, 10]).astype('float32').tolist(),
'aspect_ratios': [2.0, 3.0],
'flip': True,
'clip': True,
'steps': np.array([1.25, 1.25]).astype('float32').tolist(),
'offset': 0.5,
'variance': np.array([0.1, 0.1, 0.2, 0.2], dtype=np.float).flatten(),
'min_max_aspect_ratios_order': True
}

prior_box_attrs_list = [prior_box_attrs_default,
prior_box_max_sizes_none, prior_box_flip_clip_false, prior_box_attrs_mmar_order_true]

layer_w = 32
layer_h = 32

image_w = 40
image_h = 40

input_channels = 2
image_channels = 3
batch_size = 10

input_data = np.random.random(
(batch_size, input_channels, layer_w,
layer_h)).astype('float32')

image_data = np.random.random(
(batch_size, image_channels, image_w,
image_h)).astype('float32')

for item in prior_box_attrs_list:
pred_pdpd = prior_box(item['name'], input_data, image_data, item)

0 comments on commit f83cf4b

Please sign in to comment.