Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
a9919903
P
Paddle
项目概览
Crayon鑫
/
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看板
未验证
提交
a9919903
编写于
7月 29, 2022
作者:
Z
zhiboniu
提交者:
GitHub
7月 29, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
phi_multiclass_nms3 (#44613)
上级
e439d735
变更
10
展开全部
隐藏空白更改
内联
并排
Showing
10 changed file
with
910 addition
and
82 deletion
+910
-82
paddle/fluid/operators/detection/multiclass_nms_op.cc
paddle/fluid/operators/detection/multiclass_nms_op.cc
+8
-10
paddle/phi/api/yaml/legacy_api.yaml
paddle/phi/api/yaml/legacy_api.yaml
+9
-0
paddle/phi/infermeta/ternary.cc
paddle/phi/infermeta/ternary.cc
+93
-0
paddle/phi/infermeta/ternary.h
paddle/phi/infermeta/ternary.h
+15
-0
paddle/phi/kernels/CMakeLists.txt
paddle/phi/kernels/CMakeLists.txt
+2
-1
paddle/phi/kernels/cpu/multiclass_nms3_kernel.cc
paddle/phi/kernels/cpu/multiclass_nms3_kernel.cc
+627
-0
paddle/phi/kernels/multiclass_nms3_kernel.h
paddle/phi/kernels/multiclass_nms3_kernel.h
+37
-0
paddle/phi/ops/compat/multiclass_nms3_sig.cc
paddle/phi/ops/compat/multiclass_nms3_sig.cc
+36
-0
python/paddle/fluid/tests/unittests/op_test.py
python/paddle/fluid/tests/unittests/op_test.py
+1
-0
python/paddle/fluid/tests/unittests/test_multiclass_nms_op.py
...on/paddle/fluid/tests/unittests/test_multiclass_nms_op.py
+82
-71
未找到文件。
paddle/fluid/operators/detection/multiclass_nms_op.cc
浏览文件 @
a9919903
...
...
@@ -13,8 +13,10 @@ limitations under the License. */
#include <glog/logging.h>
#include "paddle/fluid/framework/infershape_utils.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/operators/detection/nms_util.h"
#include "paddle/phi/infermeta/ternary.h"
namespace
paddle
{
namespace
operators
{
...
...
@@ -609,12 +611,6 @@ class MultiClassNMS3Op : public MultiClassNMS2Op {
const
framework
::
VariableNameMap
&
outputs
,
const
framework
::
AttributeMap
&
attrs
)
:
MultiClassNMS2Op
(
type
,
inputs
,
outputs
,
attrs
)
{}
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
MultiClassNMS2Op
::
InferShape
(
ctx
);
ctx
->
SetOutputDim
(
"NmsRoisNum"
,
{
-
1
});
}
};
class
MultiClassNMS3OpMaker
:
public
MultiClassNMS2OpMaker
{
...
...
@@ -633,6 +629,10 @@ class MultiClassNMS3OpMaker : public MultiClassNMS2OpMaker {
}
// namespace operators
}
// namespace paddle
DECLARE_INFER_SHAPE_FUNCTOR
(
multiclass_nms3
,
MultiClassNMSShapeFunctor
,
PD_INFER_META
(
phi
::
MultiClassNMSInferMeta
));
namespace
ops
=
paddle
::
operators
;
REGISTER_OPERATOR
(
multiclass_nms
,
...
...
@@ -658,7 +658,5 @@ REGISTER_OPERATOR(
ops
::
MultiClassNMS3Op
,
ops
::
MultiClassNMS3OpMaker
,
paddle
::
framework
::
EmptyGradOpMaker
<
paddle
::
framework
::
OpDesc
>
,
paddle
::
framework
::
EmptyGradOpMaker
<
paddle
::
imperative
::
OpBase
>
);
REGISTER_OP_CPU_KERNEL
(
multiclass_nms3
,
ops
::
MultiClassNMSKernel
<
float
>
,
ops
::
MultiClassNMSKernel
<
double
>
);
paddle
::
framework
::
EmptyGradOpMaker
<
paddle
::
imperative
::
OpBase
>
,
MultiClassNMSShapeFunctor
);
paddle/phi/api/yaml/legacy_api.yaml
浏览文件 @
a9919903
...
...
@@ -1615,6 +1615,15 @@
func
:
multi_dot
backward
:
multi_dot_grad
-
api
:
multiclass_nms3
args
:
(Tensor bboxes, Tensor scores, Tensor rois_num, float score_threshold, int nms_top_k, int keep_top_k, float nms_threshold=0.3, bool normalized=true, float nms_eta=1.0, int background_label=0)
output
:
Tensor(out), Tensor(index), Tensor(nms_rois_num)
infer_meta
:
func
:
MultiClassNMSInferMeta
kernel
:
func
:
multiclass_nms3
optional
:
rois_num
# multinomial
-
api
:
multinomial
args
:
(Tensor x, int num_samples, bool replacement)
...
...
paddle/phi/infermeta/ternary.cc
浏览文件 @
a9919903
...
...
@@ -743,6 +743,99 @@ void LinspaceInferMeta(const MetaTensor& start,
LinspaceRawInferMeta
(
start
,
stop
,
number
,
out
);
}
void
MultiClassNMSInferMeta
(
const
MetaTensor
&
bboxes
,
const
MetaTensor
&
scores
,
const
MetaTensor
&
rois_num
,
float
score_threshold
,
int
nms_top_k
,
int
keep_top_k
,
float
nms_threshold
,
bool
normalized
,
float
nms_eta
,
int
background_label
,
MetaTensor
*
out
,
MetaTensor
*
index
,
MetaTensor
*
nms_rois_num
,
MetaConfig
config
)
{
auto
box_dims
=
bboxes
.
dims
();
auto
score_dims
=
scores
.
dims
();
auto
score_size
=
score_dims
.
size
();
if
(
config
.
is_runtime
)
{
PADDLE_ENFORCE_EQ
(
score_size
==
2
||
score_size
==
3
,
true
,
errors
::
InvalidArgument
(
"The rank of Input(Scores) must be 2 or 3"
". But received rank = %d"
,
score_size
));
PADDLE_ENFORCE_EQ
(
box_dims
.
size
(),
3
,
errors
::
InvalidArgument
(
"The rank of Input(BBoxes) must be 3"
". But received rank = %d"
,
box_dims
.
size
()));
if
(
score_size
==
3
)
{
PADDLE_ENFORCE_EQ
(
box_dims
[
2
]
==
4
||
box_dims
[
2
]
==
8
||
box_dims
[
2
]
==
16
||
box_dims
[
2
]
==
24
||
box_dims
[
2
]
==
32
,
true
,
errors
::
InvalidArgument
(
"The last dimension of Input"
"(BBoxes) must be 4 or 8, "
"represents the layout of coordinate "
"[xmin, ymin, xmax, ymax] or "
"4 points: [x1, y1, x2, y2, x3, y3, x4, y4] or "
"8 points: [xi, yi] i= 1,2,...,8 or "
"12 points: [xi, yi] i= 1,2,...,12 or "
"16 points: [xi, yi] i= 1,2,...,16"
));
PADDLE_ENFORCE_EQ
(
box_dims
[
1
],
score_dims
[
2
],
errors
::
InvalidArgument
(
"The 2nd dimension of Input(BBoxes) must be equal to "
"last dimension of Input(Scores), which represents the "
"predicted bboxes."
"But received box_dims[1](%s) != socre_dims[2](%s)"
,
box_dims
[
1
],
score_dims
[
2
]));
}
else
{
PADDLE_ENFORCE_EQ
(
box_dims
[
2
],
4
,
errors
::
InvalidArgument
(
"The last dimension of Input"
"(BBoxes) must be 4. But received dimension = %d"
,
box_dims
[
2
]));
PADDLE_ENFORCE_EQ
(
box_dims
[
1
],
score_dims
[
1
],
errors
::
InvalidArgument
(
"The 2nd dimension of Input"
"(BBoxes) must be equal to the 2nd dimension of Input(Scores). "
"But received box dimension = %d, score dimension = %d"
,
box_dims
[
1
],
score_dims
[
1
]));
}
}
PADDLE_ENFORCE_NE
(
out
,
nullptr
,
errors
::
InvalidArgument
(
"The out in MultiClassNMSInferMeta can't be nullptr."
));
PADDLE_ENFORCE_NE
(
index
,
nullptr
,
errors
::
InvalidArgument
(
"The index in MultiClassNMSInferMeta can't be nullptr."
));
// Here the box_dims[0] is not the real dimension of output.
// It will be rewritten in the computing kernel.
out
->
set_dims
(
phi
::
make_ddim
({
-
1
,
box_dims
[
2
]
+
2
}));
out
->
set_dtype
(
bboxes
.
dtype
());
index
->
set_dims
(
phi
::
make_ddim
({
-
1
,
box_dims
[
2
]
+
2
}));
index
->
set_dtype
(
DataType
::
INT32
);
nms_rois_num
->
set_dims
(
phi
::
make_ddim
({
-
1
}));
nms_rois_num
->
set_dtype
(
DataType
::
INT32
);
}
void
NllLossRawInferMeta
(
const
MetaTensor
&
input
,
const
MetaTensor
&
label
,
const
MetaTensor
&
weight
,
...
...
paddle/phi/infermeta/ternary.h
浏览文件 @
a9919903
...
...
@@ -123,6 +123,21 @@ void LinspaceInferMeta(const MetaTensor& start,
DataType
dtype
,
MetaTensor
*
out
);
void
MultiClassNMSInferMeta
(
const
MetaTensor
&
bboxes
,
const
MetaTensor
&
scores
,
const
MetaTensor
&
rois_num
,
float
score_threshold
,
int
nms_top_k
,
int
keep_top_k
,
float
nms_threshold
,
bool
normalized
,
float
nms_eta
,
int
background_label
,
MetaTensor
*
out
,
MetaTensor
*
index
,
MetaTensor
*
nms_rois_num
,
MetaConfig
config
=
MetaConfig
());
void
NllLossRawInferMeta
(
const
MetaTensor
&
input
,
const
MetaTensor
&
label
,
const
MetaTensor
&
weight
,
...
...
paddle/phi/kernels/CMakeLists.txt
浏览文件 @
a9919903
...
...
@@ -80,7 +80,8 @@ set(COMMON_KERNEL_DEPS
lod_utils
custom_kernel
string_infermeta
utf8proc
)
utf8proc
gpc
)
copy_if_different
(
${
kernel_declare_file
}
${
kernel_declare_file_final
}
)
...
...
paddle/phi/kernels/cpu/multiclass_nms3_kernel.cc
0 → 100644
浏览文件 @
a9919903
此差异已折叠。
点击以展开。
paddle/phi/kernels/multiclass_nms3_kernel.h
0 → 100644
浏览文件 @
a9919903
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "paddle/phi/core/dense_tensor.h"
namespace
phi
{
template
<
typename
T
,
typename
Context
>
void
MultiClassNMSKernel
(
const
Context
&
ctx
,
const
DenseTensor
&
bboxes
,
const
DenseTensor
&
scores
,
const
paddle
::
optional
<
DenseTensor
>&
rois_num
,
float
score_threshold
,
int
nms_top_k
,
int
keep_top_k
,
float
nms_threshold
,
bool
normalized
,
float
nms_eta
,
int
background_label
,
DenseTensor
*
out
,
DenseTensor
*
index
,
DenseTensor
*
nms_rois_num
);
}
// namespace phi
paddle/phi/ops/compat/multiclass_nms3_sig.cc
0 → 100644
浏览文件 @
a9919903
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "paddle/phi/core/compat/op_utils.h"
namespace
phi
{
KernelSignature
MultiClassNMS3OpArgumentMapping
(
const
ArgumentMappingContext
&
ctx
)
{
return
KernelSignature
(
"multiclass_nms3"
,
{
"BBoxes"
,
"Scores"
,
"RoisNum"
},
{
"score_threshold"
,
"nms_top_k"
,
"keep_top_k"
,
"nms_threshold"
,
"normalized"
,
"nms_eta"
,
"background_label"
},
{
"Out"
,
"Index"
,
"NmsRoisNum"
});
}
}
// namespace phi
PD_REGISTER_ARG_MAPPING_FN
(
multiclass_nms3
,
phi
::
MultiClassNMS3OpArgumentMapping
);
python/paddle/fluid/tests/unittests/op_test.py
浏览文件 @
a9919903
...
...
@@ -1457,6 +1457,7 @@ class OpTest(unittest.TestCase):
# see details: https://stackoverflow.com/questions/38331703/why-does-numpys-broadcasting-sometimes-allow-comparing-arrays-of-different-leng
if
expect_np
.
size
==
0
:
self
.
op_test
.
assertTrue
(
actual_np
.
size
==
0
)
# }}}
# print("actual_np, expect_np", actual_np, expect_np)
self
.
_compare_numpy
(
name
,
actual_np
,
expect_np
)
if
isinstance
(
expect
,
tuple
):
self
.
_compare_list
(
name
,
actual
,
expect
)
...
...
python/paddle/fluid/tests/unittests/test_multiclass_nms_op.py
浏览文件 @
a9919903
...
...
@@ -19,7 +19,81 @@ import copy
from
op_test
import
OpTest
import
paddle
import
paddle.fluid
as
fluid
from
paddle.fluid
import
Program
,
program_guard
from
paddle.fluid
import
Program
,
program_guard
,
in_dygraph_mode
,
_non_static_mode
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle
import
_C_ops
def
multiclass_nms3
(
bboxes
,
scores
,
rois_num
=
None
,
score_threshold
=
0.3
,
nms_top_k
=
1000
,
keep_top_k
=
100
,
nms_threshold
=
0.3
,
normalized
=
True
,
nms_eta
=
1.
,
background_label
=-
1
,
return_index
=
True
,
return_rois_num
=
True
,
name
=
None
):
helper
=
LayerHelper
(
'multiclass_nms3'
,
**
locals
())
if
in_dygraph_mode
():
attrs
=
(
score_threshold
,
nms_top_k
,
keep_top_k
,
nms_threshold
,
normalized
,
nms_eta
,
background_label
)
output
,
index
,
nms_rois_num
=
_C_ops
.
final_state_multiclass_nms3
(
bboxes
,
scores
,
rois_num
,
*
attrs
)
if
not
return_index
:
index
=
None
return
output
,
index
,
nms_rois_num
elif
_non_static_mode
():
attrs
=
(
'background_label'
,
background_label
,
'score_threshold'
,
score_threshold
,
'nms_top_k'
,
nms_top_k
,
'nms_threshold'
,
nms_threshold
,
'keep_top_k'
,
keep_top_k
,
'nms_eta'
,
nms_eta
,
'normalized'
,
normalized
)
output
,
index
,
nms_rois_num
=
_C_ops
.
multiclass_nms3
(
bboxes
,
scores
,
rois_num
,
*
attrs
)
if
not
return_index
:
index
=
None
return
output
,
index
,
nms_rois_num
else
:
output
=
helper
.
create_variable_for_type_inference
(
dtype
=
bboxes
.
dtype
)
index
=
helper
.
create_variable_for_type_inference
(
dtype
=
'int32'
)
inputs
=
{
'BBoxes'
:
bboxes
,
'Scores'
:
scores
}
outputs
=
{
'Out'
:
output
,
'Index'
:
index
}
if
rois_num
is
not
None
:
inputs
[
'RoisNum'
]
=
rois_num
if
return_rois_num
:
nms_rois_num
=
helper
.
create_variable_for_type_inference
(
dtype
=
'int32'
)
outputs
[
'NmsRoisNum'
]
=
nms_rois_num
helper
.
append_op
(
type
=
"multiclass_nms3"
,
inputs
=
inputs
,
attrs
=
{
'background_label'
:
background_label
,
'score_threshold'
:
score_threshold
,
'nms_top_k'
:
nms_top_k
,
'nms_threshold'
:
nms_threshold
,
'keep_top_k'
:
keep_top_k
,
'nms_eta'
:
nms_eta
,
'normalized'
:
normalized
},
outputs
=
outputs
)
output
.
stop_gradient
=
True
index
.
stop_gradient
=
True
if
not
return_index
:
index
=
None
if
not
return_rois_num
:
nms_rois_num
=
None
return
output
,
nms_rois_num
,
index
def
softmax
(
x
):
...
...
@@ -541,8 +615,9 @@ class TestMulticlassNMS2LoDInput(TestMulticlassNMSLoDInput):
'normalized'
:
normalized
,
}
def
test_check_output
(
self
):
self
.
check_output
()
def
test_check_output
(
self
):
self
.
check_output
()
class
TestMulticlassNMS2LoDNoOutput
(
TestMulticlassNMS2LoDInput
):
...
...
@@ -590,6 +665,7 @@ class TestMulticlassNMSError(unittest.TestCase):
class
TestMulticlassNMS3Op
(
TestMulticlassNMS2Op
):
def
setUp
(
self
):
self
.
python_api
=
multiclass_nms3
self
.
set_argument
()
N
=
7
M
=
1200
...
...
@@ -623,8 +699,8 @@ class TestMulticlassNMS3Op(TestMulticlassNMS2Op):
self
.
op_type
=
'multiclass_nms3'
self
.
inputs
=
{
'BBoxes'
:
boxes
,
'Scores'
:
scores
}
self
.
outputs
=
{
'Out'
:
(
nmsed_outs
,
[
lod
])
,
'Index'
:
(
index_outs
,
[
lod
])
,
'Out'
:
nmsed_outs
,
'Index'
:
index_outs
,
'NmsRoisNum'
:
np
.
array
(
lod
).
astype
(
'int32'
)
}
self
.
attrs
=
{
...
...
@@ -638,7 +714,7 @@ class TestMulticlassNMS3Op(TestMulticlassNMS2Op):
}
def
test_check_output
(
self
):
self
.
check_output
()
self
.
check_output
(
check_eager
=
True
)
class
TestMulticlassNMS3OpNoOutput
(
TestMulticlassNMS3Op
):
...
...
@@ -649,71 +725,6 @@ class TestMulticlassNMS3OpNoOutput(TestMulticlassNMS3Op):
self
.
score_threshold
=
2.0
class
TestMulticlassNMS3LoDInput
(
TestMulticlassNMS2LoDInput
):
def
setUp
(
self
):
self
.
set_argument
()
M
=
1200
C
=
21
BOX_SIZE
=
4
box_lod
=
[[
1200
]]
background
=
0
nms_threshold
=
0.3
nms_top_k
=
400
keep_top_k
=
200
score_threshold
=
self
.
score_threshold
normalized
=
False
scores
=
np
.
random
.
random
((
M
,
C
)).
astype
(
'float32'
)
scores
=
np
.
apply_along_axis
(
softmax
,
1
,
scores
)
boxes
=
np
.
random
.
random
((
M
,
C
,
BOX_SIZE
)).
astype
(
'float32'
)
boxes
[:,
:,
0
]
=
boxes
[:,
:,
0
]
*
10
boxes
[:,
:,
1
]
=
boxes
[:,
:,
1
]
*
10
boxes
[:,
:,
2
]
=
boxes
[:,
:,
2
]
*
10
+
10
boxes
[:,
:,
3
]
=
boxes
[:,
:,
3
]
*
10
+
10
det_outs
,
lod
=
lod_multiclass_nms
(
boxes
,
scores
,
background
,
score_threshold
,
nms_threshold
,
nms_top_k
,
keep_top_k
,
box_lod
,
normalized
)
det_outs
=
np
.
array
(
det_outs
)
nmsed_outs
=
det_outs
[:,
:
-
1
].
astype
(
'float32'
)
if
len
(
det_outs
)
else
det_outs
self
.
op_type
=
'multiclass_nms3'
self
.
inputs
=
{
'BBoxes'
:
(
boxes
,
box_lod
),
'Scores'
:
(
scores
,
box_lod
),
'RoisNum'
:
np
.
array
(
box_lod
).
astype
(
'int32'
)
}
self
.
outputs
=
{
'Out'
:
(
nmsed_outs
,
[
lod
]),
'NmsRoisNum'
:
np
.
array
(
lod
).
astype
(
'int32'
)
}
self
.
attrs
=
{
'background_label'
:
0
,
'nms_threshold'
:
nms_threshold
,
'nms_top_k'
:
nms_top_k
,
'keep_top_k'
:
keep_top_k
,
'score_threshold'
:
score_threshold
,
'nms_eta'
:
1.0
,
'normalized'
:
normalized
,
}
def
test_check_output
(
self
):
self
.
check_output
()
class
TestMulticlassNMS3LoDNoOutput
(
TestMulticlassNMS3LoDInput
):
def
set_argument
(
self
):
# Here set 2.0 to test the case there is no outputs.
# In practical use, 0.0 < score_threshold < 1.0
self
.
score_threshold
=
2.0
if
__name__
==
'__main__'
:
paddle
.
enable_static
()
unittest
.
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录