Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
8fc1cf60
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看板
未验证
提交
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录