Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
f3415ec5
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f3415ec5
编写于
2月 01, 2018
作者:
D
dangqingqing
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Follow comments.
上级
53788640
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
72 addition
and
56 deletion
+72
-56
paddle/operators/bipartite_match_op.cc
paddle/operators/bipartite_match_op.cc
+12
-6
paddle/operators/multiclass_nms_op.cc
paddle/operators/multiclass_nms_op.cc
+57
-47
python/paddle/v2/fluid/tests/test_bipartite_match_op.py
python/paddle/v2/fluid/tests/test_bipartite_match_op.py
+2
-2
python/paddle/v2/fluid/tests/test_multiclass_nms_op.py
python/paddle/v2/fluid/tests/test_multiclass_nms_op.py
+1
-1
未找到文件。
paddle/operators/bipartite_match_op.cc
浏览文件 @
f3415ec5
/* Copyright (c) 201
6
PaddlePaddle Authors. All Rights Reserve.
/* Copyright (c) 201
8
PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
@@ -28,12 +28,18 @@ class BipartiteMatchOp : public framework::OperatorWithKernel {
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"DistMat"
),
"Input(DistMat) of BipartiteMatch should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"ColToRowMatchIndices"
),
"Output(ColToRowMatchIndices) of BipartiteMatch should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"ColToRowMatchDist"
),
"Output(ColToRowMatchDist) of BipartiteMatch should not be null."
);
auto
dims
=
ctx
->
GetInputDim
(
"DistMat"
);
PADDLE_ENFORCE_EQ
(
dims
.
size
(),
2
,
"The rank of Input(DistMat) must be 2."
);
ctx
->
SetOutputDim
(
"ColToRowMatchIndices"
,
dims
);
ctx
->
SetOutputDim
(
"ColToRowMatchDis"
,
dims
);
ctx
->
SetOutputDim
(
"ColToRowMatchDis
t
"
,
dims
);
}
};
...
...
@@ -91,7 +97,7 @@ class BipartiteMatchKernel : public framework::OpKernel<T> {
void
Compute
(
const
framework
::
ExecutionContext
&
context
)
const
override
{
auto
*
dist_mat
=
context
.
Input
<
LoDTensor
>
(
"DistMat"
);
auto
*
match_indices
=
context
.
Output
<
Tensor
>
(
"ColToRowMatchIndices"
);
auto
*
match_dist
=
context
.
Output
<
Tensor
>
(
"ColToRowMatchDis"
);
auto
*
match_dist
=
context
.
Output
<
Tensor
>
(
"ColToRowMatchDis
t
"
);
auto
&
dev_ctx
=
context
.
device_context
<
platform
::
CPUDeviceContext
>
();
...
...
@@ -148,13 +154,13 @@ class BipartiteMatchOpMaker : public framework::OpProtoAndCheckerMaker {
"Otherwise, it means B[j] is matched to row "
"ColToRowMatchIndices[i][j] in i-th instance. The row number of "
"i-th instance is saved in ColToRowMatchIndices[i][j]."
);
AddOutput
(
"ColToRowMatchDis"
,
AddOutput
(
"ColToRowMatchDis
t
"
,
"(Tensor) A 2-D Tensor with shape [N, M] in float type. "
"N is batch size. If ColToRowMatchIndices[i][j] is -1, "
"ColToRowMatchDis[i][j] is also -1.0. Otherwise, assumed "
"ColToRowMatchDis
t
[i][j] is also -1.0. Otherwise, assumed "
"ColToRowMatchIndices[i][j] = d, and the row offsets of each "
"instance are called LoD. Then "
"ColToRowMatchDis[i][j] = DistMat[d+LoD[i]][j]"
);
"ColToRowMatchDis
t
[i][j] = DistMat[d+LoD[i]][j]"
);
AddComment
(
R"DOC(
This operator is a greedy bipartite matching algorithm, which is used to
obtain the matching with the maximum distance based on the input
...
...
paddle/operators/multiclass_nms_op.cc
浏览文件 @
f3415ec5
/* Copyright (c) 201
6
PaddlePaddle Authors. All Rights Reserve.
/* Copyright (c) 201
8
PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
...
...
@@ -24,25 +24,33 @@ using LoDTensor = framework::LoDTensor;
constexpr
int64_t
kOutputDim
=
6
;
constexpr
int64_t
kBBoxSize
=
4
;
class
Multi
c
lassNMSOp
:
public
framework
::
OperatorWithKernel
{
class
Multi
C
lassNMSOp
:
public
framework
::
OperatorWithKernel
{
public:
using
framework
::
OperatorWithKernel
::
OperatorWithKernel
;
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"B
b
oxes"
),
"Input(B
boxes) of Multic
lassNMS should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"B
B
oxes"
),
"Input(B
Boxes) of MultiC
lassNMS should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"Scores"
),
"Input(Scores) of MulticlassNMS should not be null."
);
"Input(Scores) of MultiClassNMS should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"Out"
),
"Output(Out) of MultiClassNMS should not be null."
);
auto
box_dims
=
ctx
->
GetInputDim
(
"B
b
oxes"
);
auto
box_dims
=
ctx
->
GetInputDim
(
"B
B
oxes"
);
auto
score_dims
=
ctx
->
GetInputDim
(
"Scores"
);
PADDLE_ENFORCE_EQ
(
box_dims
.
size
(),
2
,
"The rank of Input(B
boxes) must be 3
."
);
"The rank of Input(B
Boxes) must be 2
."
);
PADDLE_ENFORCE_EQ
(
score_dims
.
size
(),
3
,
"The rank of Input(Scores) must be 3."
);
PADDLE_ENFORCE_EQ
(
box_dims
[
1
],
4
);
PADDLE_ENFORCE_EQ
(
box_dims
[
0
],
score_dims
[
2
]);
PADDLE_ENFORCE_EQ
(
box_dims
[
1
],
4
,
"The 2nd dimension of Input(BBoxes) must be 4, "
"represents the layout of coordinate "
"[xmin, ymin, xmax, ymax]"
);
PADDLE_ENFORCE_EQ
(
box_dims
[
0
],
score_dims
[
2
],
"The 1st dimensiong of Input(BBoxes) must be equal to "
"3rd dimension of Input(Scores), which represents the "
"predicted bboxes."
);
// Here the box_dims[0] is not the real dimension of output.
// It will be rewritten in the computing kernel.
...
...
@@ -86,15 +94,16 @@ static inline void GetMaxScoreIndex(
template
<
class
T
>
T
BBoxArea
(
const
T
*
box
,
const
bool
normalized
)
{
if
(
box
[
2
]
<
box
[
0
]
||
box
[
3
]
<
box
[
1
])
{
// If bbox is invalid (e.g. xmax < xmin or ymax < ymin), return 0.
return
T
(
0.
);
// If coordinate values are is invalid
// (e.g. xmax < xmin or ymax < ymin), return 0.
return
static_cast
<
T
>
(
0.
);
}
else
{
const
T
w
=
box
[
2
]
-
box
[
0
];
const
T
h
=
box
[
3
]
-
box
[
1
];
if
(
normalized
)
{
return
w
*
h
;
}
else
{
// If
bbox is
not within range [0, 1].
// If
coordinate values are
not within range [0, 1].
return
(
w
+
1
)
*
(
h
+
1
);
}
}
...
...
@@ -121,7 +130,7 @@ static inline T JaccardOverlap(const T* box1, const T* box2,
}
template
<
typename
T
>
class
Multi
c
lassNMSKernel
:
public
framework
::
OpKernel
<
T
>
{
class
Multi
C
lassNMSKernel
:
public
framework
::
OpKernel
<
T
>
{
public:
void
NMSFast
(
const
Tensor
&
bbox
,
const
Tensor
&
scores
,
const
T
score_threshold
,
const
T
nms_threshold
,
const
T
eta
,
...
...
@@ -163,10 +172,10 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
}
}
void
Multi
c
lassNMS
(
const
framework
::
ExecutionContext
&
ctx
,
void
Multi
C
lassNMS
(
const
framework
::
ExecutionContext
&
ctx
,
const
Tensor
&
scores
,
const
Tensor
&
bboxes
,
std
::
map
<
int
,
std
::
vector
<
int
>>
*
indices
,
int
*
num_nmsed_out
)
const
{
std
::
map
<
int
,
std
::
vector
<
int
>>
&
indices
,
int
&
num_nmsed_out
)
const
{
int64_t
background_label
=
ctx
.
Attr
<
int
>
(
"background_label"
);
int64_t
nms_top_k
=
ctx
.
Attr
<
int
>
(
"nms_top_k"
);
int64_t
keep_top_k
=
ctx
.
Attr
<
int
>
(
"keep_top_k"
);
...
...
@@ -181,15 +190,15 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
if
(
c
==
background_label
)
continue
;
Tensor
score
=
scores
.
Slice
(
c
,
c
+
1
);
NMSFast
(
bboxes
,
score
,
score_threshold
,
nms_threshold
,
nms_eta
,
nms_top_k
,
&
(
(
*
indices
)
[
c
]));
num_det
+=
(
*
indices
)
[
c
].
size
();
&
(
indices
[
c
]));
num_det
+=
indices
[
c
].
size
();
}
*
num_nmsed_out
=
num_det
;
num_nmsed_out
=
num_det
;
const
T
*
scores_data
=
scores
.
data
<
T
>
();
if
(
keep_top_k
>
-
1
&&
num_det
>
keep_top_k
)
{
std
::
vector
<
std
::
pair
<
float
,
std
::
pair
<
int
,
int
>>>
score_index_pairs
;
for
(
const
auto
&
it
:
*
indices
)
{
for
(
const
auto
&
it
:
indices
)
{
int
label
=
it
.
first
;
const
T
*
sdata
=
scores_data
+
label
*
predict_dim
;
const
std
::
vector
<
int
>&
label_indices
=
it
.
second
;
...
...
@@ -212,12 +221,12 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
int
idx
=
score_index_pairs
[
j
].
second
.
second
;
new_indices
[
label
].
push_back
(
idx
);
}
new_indices
.
swap
(
*
indices
);
*
num_nmsed_out
=
keep_top_k
;
new_indices
.
swap
(
indices
);
num_nmsed_out
=
keep_top_k
;
}
}
void
Multi
c
lassOutput
(
const
Tensor
&
scores
,
const
Tensor
&
bboxes
,
void
Multi
C
lassOutput
(
const
Tensor
&
scores
,
const
Tensor
&
bboxes
,
std
::
map
<
int
,
std
::
vector
<
int
>>&
selected_indices
,
Tensor
*
outs
)
const
{
int
predict_dim
=
scores
.
dims
()[
1
];
...
...
@@ -229,23 +238,21 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
for
(
const
auto
&
it
:
selected_indices
)
{
int
label
=
it
.
first
;
const
T
*
sdata
=
scores_data
+
label
*
predict_dim
;
std
::
vector
<
int
>
indices
=
it
.
second
;
const
std
::
vector
<
int
>&
indices
=
it
.
second
;
for
(
int
j
=
0
;
j
<
indices
.
size
();
++
j
)
{
int
idx
=
indices
[
j
];
const
T
*
bdata
=
bboxes_data
+
idx
*
kBBoxSize
;
odata
[
count
*
kOutputDim
]
=
label
;
// label
odata
[
count
*
kOutputDim
+
1
]
=
sdata
[
idx
];
// score
odata
[
count
*
kOutputDim
+
2
]
=
bdata
[
0
];
// xmin
odata
[
count
*
kOutputDim
+
3
]
=
bdata
[
1
];
// ymin
odata
[
count
*
kOutputDim
+
4
]
=
bdata
[
2
];
// xmax
odata
[
count
*
kOutputDim
+
5
]
=
bdata
[
3
];
// ymax
// xmin, ymin, xmax, ymax
std
::
memcpy
(
odata
+
count
*
kOutputDim
+
2
,
bdata
,
4
*
sizeof
(
T
));
count
++
;
}
}
}
void
Compute
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
auto
*
boxes
=
ctx
.
Input
<
Tensor
>
(
"B
b
oxes"
);
auto
*
boxes
=
ctx
.
Input
<
Tensor
>
(
"B
B
oxes"
);
auto
*
scores
=
ctx
.
Input
<
Tensor
>
(
"Scores"
);
auto
*
outs
=
ctx
.
Output
<
LoDTensor
>
(
"Out"
);
...
...
@@ -262,7 +269,7 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
ins_score
.
Resize
({
class_num
,
predict_dim
});
std
::
map
<
int
,
std
::
vector
<
int
>>
indices
;
int
num_nmsed_out
=
0
;
Multi
classNMS
(
ctx
,
ins_score
,
*
boxes
,
&
indices
,
&
num_nmsed_out
);
Multi
ClassNMS
(
ctx
,
ins_score
,
*
boxes
,
indices
,
num_nmsed_out
);
all_indices
.
push_back
(
indices
);
batch_starts
.
push_back
(
batch_starts
.
back
()
+
num_nmsed_out
);
}
...
...
@@ -280,7 +287,7 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
int64_t
e
=
batch_starts
[
i
+
1
];
if
(
e
>
s
)
{
Tensor
out
=
outs
->
Slice
(
s
,
e
);
Multi
c
lassOutput
(
ins_score
,
*
boxes
,
all_indices
[
i
],
&
out
);
Multi
C
lassOutput
(
ins_score
,
*
boxes
,
all_indices
[
i
],
&
out
);
}
}
}
...
...
@@ -292,28 +299,31 @@ class MulticlassNMSKernel : public framework::OpKernel<T> {
}
};
class
Multi
c
lassNMSOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
Multi
C
lassNMSOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
public:
Multi
c
lassNMSOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
Multi
C
lassNMSOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"Bboxes"
,
"(Tensor) A 2-D Tensor with shape [M, 4] represents the location "
"predictions with M bboxes. 4 is the number of "
"each location coordinates."
);
AddInput
(
"BBoxes"
,
"(Tensor) A 2-D Tensor with shape [M, 4] represents the "
"predicted locations of M bounding bboxes. Each bounding box "
"has four coordinate values and the layout is "
"[xmin, ymin, xmax, ymax]."
);
AddInput
(
"Scores"
,
"(Tensor) A 3-D Tensor with shape [N, C, M] represents the "
"confidence predictions. N is the batch size, C is the class "
"number, M is number of predictions for each class, which is "
"the same with Bboxes."
);
"predicted confidence predictions. N is the batch size, C is the "
"class number, M is number of bounding boxes. For each category "
"there are total M scores which corresponding M bounding boxes. "
" Please note, M is equal to the 1st dimension of BBoxes. "
);
AddAttr
<
int
>
(
"background_label"
,
"(int64_t, defalut: 0) "
"The index of background label, the background label will be ignored."
)
"The index of background label, the background label will be ignored. "
"If set to -1, then all categories will be considered."
)
.
SetDefault
(
0
);
AddAttr
<
float
>
(
"score_threshold"
,
"(float) "
"
Only consider detections whose confidences are larger than
"
"
a threshold
. If not provided, consider all boxes."
);
"
Threshold to filter out bounding boxes with low
"
"
confidence score
. If not provided, consider all boxes."
);
AddAttr
<
int
>
(
"nms_top_k"
,
"(int64_t) "
"Maximum number of detections to be kept according to the "
...
...
@@ -368,8 +378,8 @@ value which is -1.
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OPERATOR
(
multiclass_nms
,
ops
::
Multi
c
lassNMSOp
,
ops
::
Multi
c
lassNMSOpMaker
,
REGISTER_OPERATOR
(
multiclass_nms
,
ops
::
Multi
C
lassNMSOp
,
ops
::
Multi
C
lassNMSOpMaker
,
paddle
::
framework
::
EmptyGradOpMaker
);
REGISTER_OP_CPU_KERNEL
(
multiclass_nms
,
ops
::
Multi
c
lassNMSKernel
<
float
>
,
ops
::
Multi
c
lassNMSKernel
<
double
>
);
REGISTER_OP_CPU_KERNEL
(
multiclass_nms
,
ops
::
Multi
C
lassNMSKernel
<
float
>
,
ops
::
Multi
C
lassNMSKernel
<
double
>
);
python/paddle/v2/fluid/tests/test_bipartite_match_op.py
浏览文件 @
f3415ec5
...
...
@@ -72,7 +72,7 @@ class TestBipartiteMatchOpWithLoD(OpTest):
self
.
inputs
=
{
'DistMat'
:
(
dist
,
lod
)}
self
.
outputs
=
{
'ColToRowMatchIndices'
:
(
match_indices
),
'ColToRowMatchDis'
:
(
match_dist
),
'ColToRowMatchDis
t
'
:
(
match_dist
),
}
def
test_check_output
(
self
):
...
...
@@ -89,7 +89,7 @@ class TestBipartiteMatchOpWithoutLoD(OpTest):
self
.
inputs
=
{
'DistMat'
:
dist
}
self
.
outputs
=
{
'ColToRowMatchIndices'
:
match_indices
,
'ColToRowMatchDis'
:
match_dist
,
'ColToRowMatchDis
t
'
:
match_dist
,
}
def
test_check_output
(
self
):
...
...
python/paddle/v2/fluid/tests/test_multiclass_nms_op.py
浏览文件 @
f3415ec5
...
...
@@ -190,7 +190,7 @@ class TestMulticlassNMSOp(OpTest):
nmsed_outs
=
np
.
array
(
nmsed_outs
).
astype
(
'float32'
)
self
.
op_type
=
'multiclass_nms'
self
.
inputs
=
{
'B
b
oxes'
:
boxes
,
'Scores'
:
scores
}
self
.
inputs
=
{
'B
B
oxes'
:
boxes
,
'Scores'
:
scores
}
self
.
outputs
=
{
'Out'
:
(
nmsed_outs
,
[
lod
])}
self
.
attrs
=
{
'background_label'
:
0
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录