[FrontEnd]Paddle_Op_Conversion_prior_box (#7639)
* Paddle_Op_Conversion_prior_box * use default_opset * apply review comments * const type variables modification
This commit is contained in:
112
ngraph/frontend/paddlepaddle/src/op/prior_box.cpp
Normal file
112
ngraph/frontend/paddlepaddle/src/op/prior_box.cpp
Normal file
@@ -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
|
||||
@@ -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);
|
||||
@@ -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},
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user