Commit ef4203ae authored by Ilya Churaev's avatar Ilya Churaev Committed by Scott Cyphers

Port PR 4114 on master (#4215)

* Added 3 new attributes to PriorBox and reworked shape inference to be aligned with OpenVINO Model Optimizer PriorBox translation rules.

* Correctly handle scale_all_sizes in PriorBox op shape inference

* Fixed PriorBox unit tests
Co-authored-by: 's avatarSergey Lyalin <sergey.lyalin@intel.com>
parent f733b641
......@@ -66,22 +66,10 @@ void op::PriorBox::validate_and_infer_types()
const_shape->get_shape());
auto layer_shape = const_shape->get_shape_val();
size_t num_priors = 0;
// {Prior boxes, Variance-adjusted prior boxes}
if (m_attrs.scale_all_sizes)
{
num_priors = ((m_attrs.flip ? 2 : 1) * m_attrs.aspect_ratio.size() + 1) *
m_attrs.min_size.size() +
m_attrs.max_size.size();
}
else
{
num_priors =
(m_attrs.flip ? 2 : 1) * m_attrs.aspect_ratio.size() + m_attrs.min_size.size() - 1;
}
set_output_type(
0, element::f32, Shape{2, 4 * layer_shape[0] * layer_shape[1] * num_priors});
set_output_type(0,
element::f32,
Shape{2, 4 * layer_shape[0] * layer_shape[1] * number_of_priors(m_attrs)});
}
else
{
......@@ -94,3 +82,49 @@ shared_ptr<Node> op::PriorBox::copy_with_new_args(const NodeVector& new_args) co
check_new_args_count(this, new_args);
return make_shared<PriorBox>(new_args.at(0), new_args.at(1), m_attrs);
}
size_t op::PriorBox::number_of_priors(const PriorBoxAttrs& attrs)
{
// Starting with 0 number of prior and then various conditions on attributes will contribute
// real number of prior boxes as PriorBox is a fat thing with several modes of
// operation that will be checked in order in the next statements.
size_t num_priors = 0;
// Total number of boxes around each point; depends on whether flipped boxes are included
// plus one box 1x1.
size_t total_aspect_ratios = normalized_aspect_ratio(attrs.aspect_ratio, attrs.flip).size();
if (attrs.scale_all_sizes)
num_priors = total_aspect_ratios * attrs.min_size.size() + attrs.max_size.size();
else
num_priors = total_aspect_ratios + attrs.min_size.size() - 1;
if (!attrs.fixed_size.empty())
num_priors = total_aspect_ratios * attrs.fixed_size.size();
for (auto density : attrs.density)
{
auto rounded_density = static_cast<size_t>(density);
auto density_2d = (rounded_density * rounded_density - 1);
if (!attrs.fixed_ratio.empty())
num_priors += attrs.fixed_ratio.size() * density_2d;
else
num_priors += total_aspect_ratios * density_2d;
}
return num_priors;
}
std::vector<float> op::PriorBox::normalized_aspect_ratio(const std::vector<float>& aspect_ratio,
bool flip)
{
std::set<float> unique_ratios;
for (auto ratio : aspect_ratio)
{
unique_ratios.insert(std::round(ratio * 1e6) / 1e6);
if (flip)
unique_ratios.insert(std::round(1 / ratio * 1e6) / 1e6);
}
unique_ratios.insert(1);
return std::vector<float>(unique_ratios.begin(), unique_ratios.end());
}
\ No newline at end of file
......@@ -36,6 +36,9 @@ namespace ngraph
std::vector<float> min_size;
std::vector<float> max_size;
std::vector<float> aspect_ratio;
std::vector<float> density;
std::vector<float> fixed_ratio;
std::vector<float> fixed_size;
bool clip = false;
bool flip = false;
float step = 1.0f;
......@@ -68,6 +71,11 @@ namespace ngraph
virtual std::shared_ptr<Node>
copy_with_new_args(const NodeVector& new_args) const override;
static size_t number_of_priors(const PriorBoxAttrs& attrs);
static std::vector<float>
normalized_aspect_ratio(const std::vector<float>& aspect_ratio, bool flip);
const PriorBoxAttrs& get_attrs() const { return m_attrs; }
private:
PriorBoxAttrs m_attrs;
......
......@@ -74,25 +74,25 @@ TEST(type_prop_layers, prior_box1)
{
op::PriorBoxAttrs attrs;
attrs.min_size = {2.0f, 3.0f};
attrs.aspect_ratio = {1.0f, 2.0f, 0.5f};
attrs.aspect_ratio = {1.5f, 2.0f, 2.5f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {32, 32});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
auto pb = make_shared<op::PriorBox>(layer_shape, image_shape, attrs);
ASSERT_EQ(pb->get_shape(), (Shape{2, 16384}));
ASSERT_EQ(pb->get_shape(), (Shape{2, 20480}));
}
TEST(type_prop_layers, prior_box2)
{
op::PriorBoxAttrs attrs;
attrs.min_size = {2.0f, 3.0f};
attrs.aspect_ratio = {1.0f, 2.0f, 0.5f};
attrs.aspect_ratio = {1.5f, 2.0f, 2.5f};
attrs.flip = true;
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {32, 32});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
auto pb = make_shared<op::PriorBox>(layer_shape, image_shape, attrs);
ASSERT_EQ(pb->get_shape(), (Shape{2, 28672}));
ASSERT_EQ(pb->get_shape(), (Shape{2, 32768}));
}
TEST(type_prop_layers, prior_box3)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment