add detection output python api (#8389)
parent
30408e4c34
commit
1dceb99e86
@ -0,0 +1,116 @@
|
||||
# Copyright (c) 2018 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.
|
||||
# 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.
|
||||
"""
|
||||
All layers just related to the detection neural network.
|
||||
"""
|
||||
|
||||
from ..layer_helper import LayerHelper
|
||||
|
||||
__all__ = ['detection_output', ]
|
||||
|
||||
|
||||
def detection_output(scores,
|
||||
loc,
|
||||
prior_box,
|
||||
prior_box_var,
|
||||
background_label=0,
|
||||
nms_threshold=0.3,
|
||||
nms_top_k=400,
|
||||
keep_top_k=200,
|
||||
score_threshold=0.01,
|
||||
nms_eta=1.0):
|
||||
"""
|
||||
**Detection Output Layer**
|
||||
|
||||
This layer applies the NMS to the output of network and computes the
|
||||
predict bounding box location. The output's shape of this layer could
|
||||
be zero if there is no valid bounding box.
|
||||
|
||||
Args:
|
||||
scores(Variable): 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.
|
||||
loc(Variable): A 3-D Tensor with shape [N, M, 4] represents the
|
||||
predicted locations of M bounding bboxes. N is the batch size,
|
||||
and each bounding box has four coordinate values and the layout
|
||||
is [xmin, ymin, xmax, ymax].
|
||||
prior_box(Variable): A 2-D Tensor with shape [M, 4] holds M boxes,
|
||||
each box is represented as [xmin, ymin, xmax, ymax],
|
||||
[xmin, ymin] is the left top coordinate of the anchor box,
|
||||
if the input is image feature map, they are close to the origin
|
||||
of the coordinate system. [xmax, ymax] is the right bottom
|
||||
coordinate of the anchor box.
|
||||
prior_box_var(Variable): A 2-D Tensor with shape [M, 4] holds M group
|
||||
of variance.
|
||||
background_label(float): The index of background label,
|
||||
the background label will be ignored. If set to -1, then all
|
||||
categories will be considered.
|
||||
nms_threshold(float): The threshold to be used in NMS.
|
||||
nms_top_k(int): Maximum number of detections to be kept according
|
||||
to the confidences aftern 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.
|
||||
score_threshold(float): Threshold to filter out bounding boxes with
|
||||
low confidence score. If not provided, consider all boxes.
|
||||
nms_eta(float): The parameter for adaptive NMS.
|
||||
|
||||
Returns:
|
||||
The detected bounding boxes which are a Tensor.
|
||||
|
||||
Examples:
|
||||
.. code-block:: python
|
||||
|
||||
pb = layers.data(name='prior_box', shape=[10, 4],
|
||||
append_batch_size=False, dtype='float32')
|
||||
pbv = layers.data(name='prior_box_var', shape=[10, 4],
|
||||
append_batch_size=False, dtype='float32')
|
||||
loc = layers.data(name='target_box', shape=[21, 4],
|
||||
append_batch_size=False, dtype='float32')
|
||||
scores = layers.data(name='scores', shape=[2, 21, 10],
|
||||
append_batch_size=False, dtype='float32')
|
||||
nmsed_outs = fluid.layers.detection_output(scores=scores,
|
||||
loc=loc,
|
||||
prior_box=pb,
|
||||
prior_box_var=pbv)
|
||||
"""
|
||||
|
||||
helper = LayerHelper("detection_output", **locals())
|
||||
decoded_box = helper.create_tmp_variable(dtype=loc.dtype)
|
||||
helper.append_op(
|
||||
type="box_coder",
|
||||
inputs={
|
||||
'PriorBox': prior_box,
|
||||
'PriorBoxVar': prior_box_var,
|
||||
'TargetBox': loc
|
||||
},
|
||||
outputs={'OutputBox': decoded_box},
|
||||
attrs={'code_type': 'decode_center_size'})
|
||||
nmsed_outs = helper.create_tmp_variable(dtype=decoded_box.dtype)
|
||||
|
||||
helper.append_op(
|
||||
type="multiclass_nms",
|
||||
inputs={'Scores': scores,
|
||||
'BBoxes': decoded_box},
|
||||
outputs={'Out': nmsed_outs},
|
||||
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
|
||||
})
|
||||
return nmsed_outs
|
@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2018 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.
|
||||
# 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.
|
||||
|
||||
from __future__ import print_function
|
||||
import unittest
|
||||
|
||||
import paddle.v2.fluid.layers as layers
|
||||
from paddle.v2.fluid.framework import Program, program_guard
|
||||
|
||||
|
||||
class TestBook(unittest.TestCase):
|
||||
def test_detection_output(self):
|
||||
program = Program()
|
||||
with program_guard(program):
|
||||
pb = layers.data(
|
||||
name='prior_box',
|
||||
shape=[10, 4],
|
||||
append_batch_size=False,
|
||||
dtype='float32')
|
||||
pbv = layers.data(
|
||||
name='prior_box_var',
|
||||
shape=[10, 4],
|
||||
append_batch_size=False,
|
||||
dtype='float32')
|
||||
loc = layers.data(
|
||||
name='target_box',
|
||||
shape=[20, 4],
|
||||
append_batch_size=False,
|
||||
dtype='float32')
|
||||
scores = layers.data(
|
||||
name='scores',
|
||||
shape=[2, 20, 10],
|
||||
append_batch_size=False,
|
||||
dtype='float32')
|
||||
out = layers.detection_output(
|
||||
scores=scores, loc=loc, prior_box=pb, prior_box_var=pbv)
|
||||
self.assertIsNotNone(out)
|
||||
print(str(program))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in new issue