提交 19749d52 编写于 作者: C chengduoZH

refine prior_box

上级 dd6b59da
...@@ -38,8 +38,8 @@ class PriorBoxOp : public framework::OperatorWithKernel { ...@@ -38,8 +38,8 @@ class PriorBoxOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_LT(input_dims[3], image_dims[3], PADDLE_ENFORCE_LT(input_dims[3], image_dims[3],
"The width of input must smaller than image."); "The width of input must smaller than image.");
auto min_sizes = ctx->Attrs().Get<std::vector<int>>("min_sizes"); auto min_sizes = ctx->Attrs().Get<std::vector<float>>("min_sizes");
auto max_sizes = ctx->Attrs().Get<std::vector<int>>("max_sizes"); auto max_sizes = ctx->Attrs().Get<std::vector<float>>("max_sizes");
auto variances = ctx->Attrs().Get<std::vector<float>>("variances"); auto variances = ctx->Attrs().Get<std::vector<float>>("variances");
auto aspect_ratios = ctx->Attrs().Get<std::vector<float>>("aspect_ratios"); auto aspect_ratios = ctx->Attrs().Get<std::vector<float>>("aspect_ratios");
bool flip = ctx->Attrs().Get<bool>("flip"); bool flip = ctx->Attrs().Get<bool>("flip");
...@@ -47,7 +47,7 @@ class PriorBoxOp : public framework::OperatorWithKernel { ...@@ -47,7 +47,7 @@ class PriorBoxOp : public framework::OperatorWithKernel {
std::vector<float> aspect_ratios_vec; std::vector<float> aspect_ratios_vec;
ExpandAspectRatios(aspect_ratios, flip, aspect_ratios_vec); ExpandAspectRatios(aspect_ratios, flip, aspect_ratios_vec);
int num_priors = aspect_ratios_vec.size() * min_sizes.size(); size_t num_priors = aspect_ratios_vec.size() * min_sizes.size();
if (max_sizes.size() > 0) { if (max_sizes.size() > 0) {
PADDLE_ENFORCE_EQ(max_sizes.size(), min_sizes.size(), PADDLE_ENFORCE_EQ(max_sizes.size(), min_sizes.size(),
"The number of min_size and max_size must be equal."); "The number of min_size and max_size must be equal.");
...@@ -90,20 +90,20 @@ class PriorBoxOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -90,20 +90,20 @@ class PriorBoxOpMaker : public framework::OpProtoAndCheckerMaker {
"H is the height of input, W is the width of input, num_priors " "H is the height of input, W is the width of input, num_priors "
"is the box count of each position."); "is the box count of each position.");
AddAttr<std::vector<int>>("min_sizes", AddAttr<std::vector<float>>("min_sizes",
"(vector<int>) List of min sizes " "(vector<float>) List of min sizes "
"of generated prior boxes.") "of generated prior boxes.")
.AddCustomChecker([](const std::vector<int>& min_sizes) { .AddCustomChecker([](const std::vector<float>& min_sizes) {
PADDLE_ENFORCE_GT(min_sizes.size(), 0, PADDLE_ENFORCE_GT(min_sizes.size(), 0,
"Size of min_sizes must be at least 1."); "Size of min_sizes must be at least 1.");
for (size_t i = 0; i < min_sizes.size(); ++i) { for (size_t i = 0; i < min_sizes.size(); ++i) {
PADDLE_ENFORCE_GT(min_sizes[i], 0, PADDLE_ENFORCE_GT(min_sizes[i], 0.0,
"min_sizes[%d] must be positive.", i); "min_sizes[%d] must be positive.", i);
} }
}); });
AddAttr<std::vector<int>>( AddAttr<std::vector<float>>(
"max_sizes", "max_sizes",
"(vector<int>) List of max sizes of generated prior boxes."); "(vector<float>) List of max sizes of generated prior boxes.");
AddAttr<std::vector<float>>( AddAttr<std::vector<float>>(
"aspect_ratios", "aspect_ratios",
"(vector<float>) List of aspect ratios of generated prior boxes."); "(vector<float>) List of aspect ratios of generated prior boxes.");
......
...@@ -60,8 +60,8 @@ class PriorBoxOpKernel : public framework::OpKernel<T> { ...@@ -60,8 +60,8 @@ class PriorBoxOpKernel : public framework::OpKernel<T> {
auto* boxes = ctx.Output<paddle::framework::Tensor>("Boxes"); auto* boxes = ctx.Output<paddle::framework::Tensor>("Boxes");
auto* vars = ctx.Output<paddle::framework::Tensor>("Variances"); auto* vars = ctx.Output<paddle::framework::Tensor>("Variances");
auto min_sizes = ctx.Attr<std::vector<int>>("min_sizes"); auto min_sizes = ctx.Attr<std::vector<float>>("min_sizes");
auto max_sizes = ctx.Attr<std::vector<int>>("max_sizes"); auto max_sizes = ctx.Attr<std::vector<float>>("max_sizes");
auto input_aspect_ratio = ctx.Attr<std::vector<float>>("aspect_ratios"); auto input_aspect_ratio = ctx.Attr<std::vector<float>>("aspect_ratios");
auto variances = ctx.Attr<std::vector<float>>("variances"); auto variances = ctx.Attr<std::vector<float>>("variances");
auto flip = ctx.Attr<bool>("flip"); auto flip = ctx.Attr<bool>("flip");
...@@ -108,7 +108,7 @@ class PriorBoxOpKernel : public framework::OpKernel<T> { ...@@ -108,7 +108,7 @@ class PriorBoxOpKernel : public framework::OpKernel<T> {
T box_width, box_height; T box_width, box_height;
int idx = 0; int idx = 0;
for (size_t s = 0; s < min_sizes.size(); ++s) { for (size_t s = 0; s < min_sizes.size(); ++s) {
int min_size = min_sizes[s]; auto min_size = min_sizes[s];
// first prior: aspect_ratio = 1, size = min_size // first prior: aspect_ratio = 1, size = min_size
box_width = box_height = min_size; box_width = box_height = min_size;
// xmin // xmin
...@@ -124,7 +124,7 @@ class PriorBoxOpKernel : public framework::OpKernel<T> { ...@@ -124,7 +124,7 @@ class PriorBoxOpKernel : public framework::OpKernel<T> {
idx++; idx++;
if (max_sizes.size() > 0) { if (max_sizes.size() > 0) {
int max_size = max_sizes[s]; auto max_size = max_sizes[s];
// second prior: aspect_ratio = 1, // second prior: aspect_ratio = 1,
// size = sqrt(min_size * max_size) // size = sqrt(min_size * max_size)
box_width = box_height = sqrt(min_size * max_size); box_width = box_height = sqrt(min_size * max_size);
......
...@@ -14,13 +14,16 @@ ...@@ -14,13 +14,16 @@
""" """
All layers just related to the neural network. All layers just related to the neural network.
""" """
import math
from ..layer_helper import LayerHelper from ..layer_helper import LayerHelper
from ..initializer import Normal, Constant from ..initializer import Normal, Constant
from ..framework import Variable from ..framework import Variable
from ..param_attr import ParamAttr from ..param_attr import ParamAttr
from layer_function_generator import autodoc from layer_function_generator import autodoc
from tensor import concat from tensor import concat
import math
import numpy as np
from operator import mul
__all__ = [ __all__ = [
'fc', 'fc',
...@@ -64,7 +67,10 @@ __all__ = [ ...@@ -64,7 +67,10 @@ __all__ = [
'nce', 'nce',
'beam_search', 'beam_search',
'row_conv', 'row_conv',
'reshape',
'reshape_with_axis',
'multiplex', 'multiplex',
'prior_box'
'prior_boxes', 'prior_boxes',
] ]
...@@ -2996,6 +3002,40 @@ def multiplex(inputs, index): ...@@ -2996,6 +3002,40 @@ def multiplex(inputs, index):
return out return out
def reshape_with_axis(input, axis):
"""
**ReshapeWithAxis Layer**
"""
assert len(input.shape) > axis and axis >= 0, ' '
input_shape = input.shape
new_dim = [-1, reduce(mul, input_shape[axis:len(input_shape)], 1)]
helper = LayerHelper('reshape', **locals())
out = helper.create_tmp_variable(helper.input_dtype())
helper.append_op(
type='reshape',
inputs={'X': [input]},
outputs={'Out': [out]},
attrs={'shape': new_dim})
return out
def reshape(input, new_dim):
"""
**Reshape Layer**
"""
helper = LayerHelper('reshape', **locals())
out = helper.create_tmp_variable(helper.input_dtype())
helper.append_op(
type='reshape',
inputs={'X': [input]},
outputs={'Out': [out]},
attrs={'shape': new_dim})
return out
def prior_box(input, def prior_box(input,
image, image,
min_sizes, min_sizes,
...@@ -3041,13 +3081,13 @@ def prior_boxes(input_layers, ...@@ -3041,13 +3081,13 @@ def prior_boxes(input_layers,
image, image,
min_ratio, min_ratio,
max_ratio, max_ratio,
steps,
aspect_ratios, aspect_ratios,
min_dim, min_dim,
steps=None,
step_w=None, step_w=None,
step_h=None, step_h=None,
offset=0.5, offset=0.5,
variance=[0.1], variance=[0.1, 0.1, 0.1, 0.1],
flip=True, flip=True,
clip=True, clip=True,
name=None): name=None):
...@@ -3059,8 +3099,8 @@ def prior_boxes(input_layers, ...@@ -3059,8 +3099,8 @@ def prior_boxes(input_layers,
image = data, image = data,
min_ratio = 0.2, min_ratio = 0.2,
max_ratio = 0.9, max_ratio = 0.9,
steps = [8, 16, 32, 64, 100, 300], steps = [8., 16., 32., 64., 100., 300.],
aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]], aspect_ratios = [[2.], [2., 3.], [2., 3.], [2., 3.], [2.], [2.]],
min_dim = 300, min_dim = 300,
offset = 0.5, offset = 0.5,
variance = [0.1], variance = [0.1],
...@@ -3068,19 +3108,16 @@ def prior_boxes(input_layers, ...@@ -3068,19 +3108,16 @@ def prior_boxes(input_layers,
clip=True) clip=True)
""" """
assert isinstance(input_layers, list), 'input_layer should be a list.' assert isinstance(input_layers, list), 'input_layer should be a list.'
assert not step_h and not steps, ''
assert not step_w and not steps, ''
num_layer = len(input_layers) num_layer = len(input_layers)
assert num_layer > 2 # TODO(zcd): currently, num_layer must be bigger than two. assert num_layer > 2 # TODO(zcd): currently, num_layer must be bigger than two.
min_sizes = [] min_sizes = []
max_sizes = [] max_sizes = []
if num_layer > 2: if num_layer > 2:
step = int(math.floor((max_ratio - min_ratio) / (num_layer - 2))) step = int(math.floor(((max_ratio - min_ratio)) / (num_layer - 2)))
for ratio in xrange(min_ratio, max_ratio + 1, step): for ratio in xrange(min_ratio, max_ratio + 1, step):
min_sizes.append(min_dim * ratio) min_sizes.append(min_dim * ratio / 100.)
max_sizes.append(min_dim * (ratio + step)) max_sizes.append(min_dim * (ratio + step) / 100.)
min_sizes = [min_dim * .10] + min_sizes min_sizes = [min_dim * .10] + min_sizes
max_sizes = [min_dim * .20] + max_sizes max_sizes = [min_dim * .20] + max_sizes
...@@ -3091,7 +3128,7 @@ def prior_boxes(input_layers, ...@@ -3091,7 +3128,7 @@ def prior_boxes(input_layers,
assert isinstance(step_w,list) and len(step_w) == num_layer, \ assert isinstance(step_w,list) and len(step_w) == num_layer, \
'step_w should be list and input_layers and step_w should have same length' 'step_w should be list and input_layers and step_w should have same length'
if steps: if steps:
assert isinstance(steps,list) and len(step_w) == num_layer, \ assert isinstance(steps,list) and len(steps) == num_layer, \
'steps should be list and input_layers and step_w should have same length' 'steps should be list and input_layers and step_w should have same length'
step_w = steps step_w = steps
step_h = steps step_h = steps
...@@ -3100,25 +3137,25 @@ def prior_boxes(input_layers, ...@@ -3100,25 +3137,25 @@ def prior_boxes(input_layers,
'aspect_ratios should be list and input_layers and aspect_ratios should ' \ 'aspect_ratios should be list and input_layers and aspect_ratios should ' \
'have same length' 'have same length'
helper = LayerHelper("prior_box", **locals())
dtype = helper.input_dtype()
box_results = [] box_results = []
var_results = [] var_results = []
for i, input in enumerate(input_layers): for i, input in enumerate(input_layers):
min_size = min_sizes[i] min_size = min_sizes[i]
max_size = max_sizes[i] max_size = max_sizes[i]
if isinstance(min_size, list): aspect_ratio = []
if not isinstance(min_size, list):
min_size = [min_size] min_size = [min_size]
if isinstance(max_size, list): if not isinstance(max_size, list):
max_size = [max_size] max_size = [max_size]
if aspect_ratios: if aspect_ratios:
aspect_ratio = aspect_ratios[i] aspect_ratio = aspect_ratios[i]
if isinstance(aspect_ratio, list): if not isinstance(aspect_ratio, list):
aspect_ratio = [aspect_ratio] aspect_ratio = [aspect_ratio]
box, var = prior_box(input, image, min_size, max_size, aspect_ratios, box, var = prior_box(input, image, min_size, max_size, aspect_ratio,
variance, flip, clip, step_w[i], step_h[i], offset) variance, flip, clip, step_w[i]
if step_w else [], step_h[i]
if step_w else [], offset)
box_results.append(box) box_results.append(box)
var_results.append(var) var_results.append(var)
...@@ -3127,18 +3164,29 @@ def prior_boxes(input_layers, ...@@ -3127,18 +3164,29 @@ def prior_boxes(input_layers,
box = box_results[0] box = box_results[0]
var = var_results[0] var = var_results[0]
else: else:
axis = 1 axis = 3
reshaped_boxes = []
reshaped_vars = []
for i in range(len(box_results)):
reshaped_boxes += [reshape_with_axis(box_results[i], axis=axis)]
reshaped_vars += [reshape_with_axis(var_results[i], axis=axis)]
helper = LayerHelper("concat", **locals())
dtype = helper.input_dtype()
box = helper.create_tmp_variable(dtype) box = helper.create_tmp_variable(dtype)
var = helper.create_tmp_variable(dtype)
axis = 0
helper.append_op( helper.append_op(
type="concat", type="concat",
inputs={"X": box_results}, inputs={"X": reshaped_boxes},
outputs={"Out": box}, outputs={"Out": box},
attrs={'axis': axis}) attrs={'axis': axis})
var = helper.create_tmp_variable(dtype) var = helper.create_tmp_variable(dtype)
helper.append_op( helper.append_op(
type="concat", type="concat",
inputs={"X": var_results}, inputs={"X": reshaped_vars},
outputs={"Out": var}, outputs={"Out": var},
attrs={'axis': axis}) attrs={'axis': axis})
......
...@@ -65,9 +65,9 @@ class TestPriorBoxOp(OpTest): ...@@ -65,9 +65,9 @@ class TestPriorBoxOp(OpTest):
self.batch_size = 10 self.batch_size = 10
self.min_sizes = [2, 4] self.min_sizes = [2, 4]
self.min_sizes = np.array(self.min_sizes).astype('int64') self.min_sizes = np.array(self.min_sizes).astype('float32')
self.max_sizes = [5, 10] self.max_sizes = [5, 10]
self.max_sizes = np.array(self.max_sizes).astype('int64') self.max_sizes = np.array(self.max_sizes).astype('float32')
self.aspect_ratios = [2.0, 3.0] self.aspect_ratios = [2.0, 3.0]
self.flip = True self.flip = True
self.real_aspect_ratios = [1, 2.0, 1.0 / 2.0, 3.0, 1.0 / 3.0] self.real_aspect_ratios = [1, 2.0, 1.0 / 2.0, 3.0, 1.0 / 3.0]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册