Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleDetection
提交
f3415ec5
P
PaddleDetection
项目概览
PaddlePaddle
/
PaddleDetection
大约 1 年 前同步成功
通知
695
Star
11112
Fork
2696
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
184
列表
看板
标记
里程碑
合并请求
40
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
184
Issue
184
列表
看板
标记
里程碑
合并请求
40
合并请求
40
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录