-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FrontEnd]Paddle_Op_Conversion_prior_box (#7639)
* Paddle_Op_Conversion_prior_box * use default_opset * apply review comments * const type variables modification
- Loading branch information
1 parent
5ef3472
commit f83cf4b
Showing
4 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
ngraph/test/frontend/paddlepaddle/test_models/gen_scripts/generate_prior_box.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |