Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
8fc1cf60
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2305
Star
20932
Fork
5423
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
8fc1cf60
编写于
7月 27, 2022
作者:
S
shangliang Xu
提交者:
GitHub
7月 27, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add matrix_nms in python/paddle/vision/ops.py (#44357)
上级
ea91ca2f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
201 addition
and
30 deletion
+201
-30
python/paddle/fluid/tests/unittests/test_matrix_nms_op.py
python/paddle/fluid/tests/unittests/test_matrix_nms_op.py
+47
-15
python/paddle/fluid/tests/unittests/test_ops_nms.py
python/paddle/fluid/tests/unittests/test_ops_nms.py
+16
-0
python/paddle/vision/ops.py
python/paddle/vision/ops.py
+138
-15
未找到文件。
python/paddle/fluid/tests/unittests/test_matrix_nms_op.py
浏览文件 @
8fc1cf60
...
...
@@ -19,6 +19,7 @@ import copy
from
op_test
import
OpTest
import
paddle.fluid
as
fluid
from
paddle.fluid
import
Program
,
program_guard
import
paddle
def
softmax
(
x
):
...
...
@@ -237,22 +238,22 @@ class TestMatrixNMSOpGaussian(TestMatrixNMSOp):
class
TestMatrixNMSError
(
unittest
.
TestCase
):
def
test_errors
(
self
):
with
program_guard
(
Program
(),
Program
()):
M
=
1200
N
=
7
C
=
21
BOX_SIZE
=
4
nms_top_k
=
400
keep_top_k
=
200
score_threshold
=
0.01
post_threshold
=
0.
boxes_np
=
np
.
random
.
random
((
M
,
C
,
BOX_SIZE
)).
astype
(
'float32'
)
scores
=
np
.
random
.
random
((
N
*
M
,
C
)).
astype
(
'float32'
)
scores
=
np
.
apply_along_axis
(
softmax
,
1
,
scores
)
scores
=
np
.
reshape
(
scores
,
(
N
,
M
,
C
))
scores_np
=
np
.
transpose
(
scores
,
(
0
,
2
,
1
))
M
=
1200
N
=
7
C
=
21
BOX_SIZE
=
4
nms_top_k
=
400
keep_top_k
=
200
score_threshold
=
0.01
post_threshold
=
0.
boxes_np
=
np
.
random
.
random
((
M
,
C
,
BOX_SIZE
)).
astype
(
'float32'
)
scores
=
np
.
random
.
random
((
N
*
M
,
C
)).
astype
(
'float32'
)
scores
=
np
.
apply_along_axis
(
softmax
,
1
,
scores
)
scores
=
np
.
reshape
(
scores
,
(
N
,
M
,
C
))
scores_np
=
np
.
transpose
(
scores
,
(
0
,
2
,
1
))
with
program_guard
(
Program
(),
Program
()):
boxes_data
=
fluid
.
data
(
name
=
'bboxes'
,
shape
=
[
M
,
C
,
BOX_SIZE
],
dtype
=
'float32'
)
...
...
@@ -268,6 +269,12 @@ class TestMatrixNMSError(unittest.TestCase):
keep_top_k
=
keep_top_k
,
score_threshold
=
score_threshold
,
post_threshold
=
post_threshold
)
paddle
.
vision
.
ops
.
matrix_nms
(
bboxes
=
boxes_np
,
scores
=
scores_data
,
nms_top_k
=
nms_top_k
,
keep_top_k
=
keep_top_k
,
score_threshold
=
score_threshold
,
post_threshold
=
post_threshold
)
def
test_scores_Variable
():
# the scores type must be Variable
...
...
@@ -277,6 +284,12 @@ class TestMatrixNMSError(unittest.TestCase):
keep_top_k
=
keep_top_k
,
score_threshold
=
score_threshold
,
post_threshold
=
post_threshold
)
paddle
.
vision
.
ops
.
matrix_nms
(
bboxes
=
boxes_data
,
scores
=
scores_np
,
nms_top_k
=
nms_top_k
,
keep_top_k
=
keep_top_k
,
score_threshold
=
score_threshold
,
post_threshold
=
post_threshold
)
def
test_empty
():
# when all score are lower than threshold
...
...
@@ -289,6 +302,15 @@ class TestMatrixNMSError(unittest.TestCase):
post_threshold
=
post_threshold
)
except
Exception
as
e
:
self
.
fail
(
e
)
try
:
paddle
.
vision
.
ops
.
matrix_nms
(
bboxes
=
boxes_data
,
scores
=
scores_data
,
nms_top_k
=
nms_top_k
,
keep_top_k
=
keep_top_k
,
score_threshold
=
10.
,
post_threshold
=
post_threshold
)
except
Exception
as
e
:
self
.
fail
(
e
)
def
test_coverage
():
# cover correct workflow
...
...
@@ -301,6 +323,16 @@ class TestMatrixNMSError(unittest.TestCase):
post_threshold
=
post_threshold
)
except
Exception
as
e
:
self
.
fail
(
e
)
try
:
paddle
.
vision
.
ops
.
matrix_nms
(
bboxes
=
boxes_data
,
scores
=
scores_data
,
nms_top_k
=
nms_top_k
,
keep_top_k
=
keep_top_k
,
score_threshold
=
score_threshold
,
post_threshold
=
post_threshold
)
except
Exception
as
e
:
self
.
fail
(
e
)
self
.
assertRaises
(
TypeError
,
test_bboxes_Variable
)
self
.
assertRaises
(
TypeError
,
test_scores_Variable
)
...
...
python/paddle/fluid/tests/unittests/test_ops_nms.py
浏览文件 @
8fc1cf60
...
...
@@ -197,6 +197,22 @@ class TestOpsNMS(unittest.TestCase):
"origin out: {}
\n
inference model out: {}
\n
"
.
format
(
origin
,
res
))
def
test_matrix_nms_dynamic
(
self
):
for
device
in
self
.
devices
:
for
dtype
in
self
.
dtypes
:
boxes
,
scores
,
category_idxs
,
categories
=
gen_args
(
self
.
num_boxes
,
dtype
)
scores
=
np
.
random
.
rand
(
1
,
4
,
self
.
num_boxes
).
astype
(
dtype
)
paddle
.
set_device
(
device
)
out
=
paddle
.
vision
.
ops
.
matrix_nms
(
paddle
.
to_tensor
(
boxes
).
unsqueeze
(
0
),
paddle
.
to_tensor
(
scores
),
self
.
threshold
,
post_threshold
=
0.
,
nms_top_k
=
400
,
keep_top_k
=
100
,
)
if
__name__
==
'__main__'
:
unittest
.
main
()
python/paddle/vision/ops.py
浏览文件 @
8fc1cf60
...
...
@@ -24,21 +24,10 @@ from paddle.common_ops_import import *
from
paddle
import
_C_ops
__all__
=
[
#noqa
'yolo_loss'
,
'yolo_box'
,
'deform_conv2d'
,
'DeformConv2D'
,
'distribute_fpn_proposals'
,
'generate_proposals'
,
'read_file'
,
'decode_jpeg'
,
'roi_pool'
,
'RoIPool'
,
'psroi_pool'
,
'PSRoIPool'
,
'roi_align'
,
'RoIAlign'
,
'nms'
,
'yolo_loss'
,
'yolo_box'
,
'deform_conv2d'
,
'DeformConv2D'
,
'distribute_fpn_proposals'
,
'generate_proposals'
,
'read_file'
,
'decode_jpeg'
,
'roi_pool'
,
'RoIPool'
,
'psroi_pool'
,
'PSRoIPool'
,
'roi_align'
,
'RoIAlign'
,
'nms'
,
'matrix_nms'
]
...
...
@@ -1802,3 +1791,137 @@ def generate_proposals(scores,
rpn_rois_num
=
None
return
rpn_rois
,
rpn_roi_probs
,
rpn_rois_num
def
matrix_nms
(
bboxes
,
scores
,
score_threshold
,
post_threshold
,
nms_top_k
,
keep_top_k
,
use_gaussian
=
False
,
gaussian_sigma
=
2.
,
background_label
=
0
,
normalized
=
True
,
return_index
=
False
,
return_rois_num
=
True
,
name
=
None
):
"""
This operator does matrix non maximum suppression (NMS).
First selects a subset of candidate bounding boxes that have higher scores
than score_threshold (if provided), then the top k candidate is selected if
nms_top_k is larger than -1. Score of the remaining candidate are then
decayed according to the Matrix NMS scheme.
Aftern NMS step, at most keep_top_k number of total bboxes are to be kept
per image if keep_top_k is larger than -1.
Args:
bboxes (Tensor): A 3-D Tensor with shape [N, M, 4] represents the
predicted locations of M bounding bboxes,
N is the batch size. Each bounding box has four
coordinate values and the layout is
[xmin, ymin, xmax, ymax], when box size equals to 4.
The data type is float32 or float64.
scores (Tensor): A 3-D Tensor with shape [N, C, M]
represents the 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 2nd dimension
of BBoxes. The data type is float32 or float64.
score_threshold (float): Threshold to filter out bounding boxes with
low confidence score.
post_threshold (float): Threshold to filter out bounding boxes with
low confidence score AFTER decaying.
nms_top_k (int): Maximum number of detections to be kept according to
the confidences after the filtering detections based
on score_threshold.
keep_top_k (int): Number of total bboxes to be kept per image after NMS
step. -1 means keeping all bboxes after NMS step.
use_gaussian (bool): Use Gaussian as the decay function. Default: False
gaussian_sigma (float): Sigma for Gaussian decay function. Default: 2.0
background_label (int): The index of background label, the background
label will be ignored. If set to -1, then all
categories will be considered. Default: 0
normalized (bool): Whether detections are normalized. Default: True
return_index(bool): Whether return selected index. Default: False
return_rois_num(bool): whether return rois_num. Default: True
name(str): Name of the matrix nms op. Default: None.
Returns:
A tuple with three Tensor: (Out, Index, RoisNum) if return_index is True,
otherwise, a tuple with two Tensor (Out, RoisNum) is returned.
Out (Tensor): A 2-D Tensor with shape [No, 6] containing the
detection results.
Each row has 6 values: [label, confidence, xmin, ymin, xmax, ymax]
Index (Tensor): A 2-D Tensor with shape [No, 1] containing the
selected indices, which are absolute values cross batches.
rois_num (Tensor): A 1-D Tensor with shape [N] containing
the number of detected boxes in each image.
Examples:
.. code-block:: python
import paddle
from paddle.vision.ops import matrix_nms
boxes = paddle.rand([4, 1, 4])
boxes[..., 2] = boxes[..., 0] + boxes[..., 2]
boxes[..., 3] = boxes[..., 1] + boxes[..., 3]
scores = paddle.rand([4, 80, 1])
out = matrix_nms(bboxes=boxes, scores=scores, background_label=0,
score_threshold=0.5, post_threshold=0.1,
nms_top_k=400, keep_top_k=200, normalized=False)
"""
check_variable_and_dtype
(
bboxes
,
'BBoxes'
,
[
'float32'
,
'float64'
],
'matrix_nms'
)
check_variable_and_dtype
(
scores
,
'Scores'
,
[
'float32'
,
'float64'
],
'matrix_nms'
)
check_type
(
score_threshold
,
'score_threshold'
,
float
,
'matrix_nms'
)
check_type
(
post_threshold
,
'post_threshold'
,
float
,
'matrix_nms'
)
check_type
(
nms_top_k
,
'nums_top_k'
,
int
,
'matrix_nms'
)
check_type
(
keep_top_k
,
'keep_top_k'
,
int
,
'matrix_nms'
)
check_type
(
normalized
,
'normalized'
,
bool
,
'matrix_nms'
)
check_type
(
use_gaussian
,
'use_gaussian'
,
bool
,
'matrix_nms'
)
check_type
(
gaussian_sigma
,
'gaussian_sigma'
,
float
,
'matrix_nms'
)
check_type
(
background_label
,
'background_label'
,
int
,
'matrix_nms'
)
if
in_dygraph_mode
():
attrs
=
(
'background_label'
,
background_label
,
'score_threshold'
,
score_threshold
,
'post_threshold'
,
post_threshold
,
'nms_top_k'
,
nms_top_k
,
'gaussian_sigma'
,
gaussian_sigma
,
'use_gaussian'
,
use_gaussian
,
'keep_top_k'
,
keep_top_k
,
'normalized'
,
normalized
)
out
,
index
,
rois_num
=
_C_ops
.
matrix_nms
(
bboxes
,
scores
,
*
attrs
)
if
not
return_index
:
index
=
None
if
not
return_rois_num
:
rois_num
=
None
return
out
,
rois_num
,
index
else
:
helper
=
LayerHelper
(
'matrix_nms'
,
**
locals
())
output
=
helper
.
create_variable_for_type_inference
(
dtype
=
bboxes
.
dtype
)
index
=
helper
.
create_variable_for_type_inference
(
dtype
=
'int32'
)
outputs
=
{
'Out'
:
output
,
'Index'
:
index
}
if
return_rois_num
:
rois_num
=
helper
.
create_variable_for_type_inference
(
dtype
=
'int32'
)
outputs
[
'RoisNum'
]
=
rois_num
helper
.
append_op
(
type
=
"matrix_nms"
,
inputs
=
{
'BBoxes'
:
bboxes
,
'Scores'
:
scores
},
attrs
=
{
'background_label'
:
background_label
,
'score_threshold'
:
score_threshold
,
'post_threshold'
:
post_threshold
,
'nms_top_k'
:
nms_top_k
,
'gaussian_sigma'
:
gaussian_sigma
,
'use_gaussian'
:
use_gaussian
,
'keep_top_k'
:
keep_top_k
,
'normalized'
:
normalized
},
outputs
=
outputs
)
output
.
stop_gradient
=
True
if
not
return_index
:
index
=
None
if
not
return_rois_num
:
rois_num
=
None
return
output
,
rois_num
,
index
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录