From d38b869438d3389e333ecbae04d817e104eafc73 Mon Sep 17 00:00:00 2001 From: qingqing01 Date: Sun, 11 Feb 2018 10:30:04 +0800 Subject: [PATCH] Fix the input dimension for multiclass_nms_op. (#8232) --- paddle/fluid/operators/multiclass_nms_op.cc | 29 ++++++++++++------- .../v2/fluid/tests/test_multiclass_nms_op.py | 10 +++---- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/paddle/fluid/operators/multiclass_nms_op.cc b/paddle/fluid/operators/multiclass_nms_op.cc index b2934f69cc9..168e6f85d6a 100644 --- a/paddle/fluid/operators/multiclass_nms_op.cc +++ b/paddle/fluid/operators/multiclass_nms_op.cc @@ -38,22 +38,22 @@ class MultiClassNMSOp : public framework::OperatorWithKernel { auto box_dims = ctx->GetInputDim("BBoxes"); auto score_dims = ctx->GetInputDim("Scores"); - PADDLE_ENFORCE_EQ(box_dims.size(), 2, - "The rank of Input(BBoxes) must be 2."); + PADDLE_ENFORCE_EQ(box_dims.size(), 3, + "The rank of Input(BBoxes) must be 3."); 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[2], 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], + PADDLE_ENFORCE_EQ(box_dims[1], 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. - ctx->SetOutputDim("Out", {box_dims[0], 6}); + ctx->SetOutputDim("Out", {box_dims[1], 6}); } protected: @@ -260,15 +260,20 @@ class MultiClassNMSKernel : public framework::OpKernel { int64_t batch_size = score_dims[0]; int64_t class_num = score_dims[1]; int64_t predict_dim = score_dims[2]; + int64_t box_dim = boxes->dims()[2]; std::vector>> all_indices; std::vector batch_starts = {0}; for (int64_t i = 0; i < batch_size; ++i) { Tensor ins_score = scores->Slice(i, i + 1); ins_score.Resize({class_num, predict_dim}); + + Tensor ins_boxes = boxes->Slice(i, i + 1); + ins_boxes.Resize({predict_dim, box_dim}); + std::map> indices; int num_nmsed_out = 0; - MultiClassNMS(ctx, ins_score, *boxes, indices, num_nmsed_out); + MultiClassNMS(ctx, ins_score, ins_boxes, indices, num_nmsed_out); all_indices.push_back(indices); batch_starts.push_back(batch_starts.back() + num_nmsed_out); } @@ -282,11 +287,15 @@ class MultiClassNMSKernel : public framework::OpKernel { for (int64_t i = 0; i < batch_size; ++i) { Tensor ins_score = scores->Slice(i, i + 1); ins_score.Resize({class_num, predict_dim}); + + Tensor ins_boxes = boxes->Slice(i, i + 1); + ins_boxes.Resize({predict_dim, box_dim}); + int64_t s = batch_starts[i]; int64_t e = batch_starts[i + 1]; if (e > s) { Tensor out = outs->Slice(s, e); - MultiClassOutput(ins_score, *boxes, all_indices[i], &out); + MultiClassOutput(ins_score, ins_boxes, all_indices[i], &out); } } } @@ -303,9 +312,9 @@ class MultiClassNMSOpMaker : public framework::OpProtoAndCheckerMaker { MultiClassNMSOpMaker(OpProto* proto, OpAttrChecker* op_checker) : OpProtoAndCheckerMaker(proto, op_checker) { 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 " + "(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]."); AddInput("Scores", "(Tensor) A 3-D Tensor with shape [N, C, M] represents the " diff --git a/python/paddle/v2/fluid/tests/test_multiclass_nms_op.py b/python/paddle/v2/fluid/tests/test_multiclass_nms_op.py index 3b80d2359b0..529223cf40d 100644 --- a/python/paddle/v2/fluid/tests/test_multiclass_nms_op.py +++ b/python/paddle/v2/fluid/tests/test_multiclass_nms_op.py @@ -137,7 +137,7 @@ def batched_multiclass_nms(boxes, scores, background, score_threshold, det_outs = [] lod = [0] for n in range(batch_size): - nmsed_outs, nmsed_num = multiclass_nms(boxes, scores[n], background, + nmsed_outs, nmsed_num = multiclass_nms(boxes[n], scores[n], background, score_threshold, nms_threshold, nms_top_k, keep_top_k) lod.append(lod[-1] + nmsed_num) @@ -145,7 +145,7 @@ def batched_multiclass_nms(boxes, scores, background, score_threshold, for c, indices in nmsed_outs.iteritems(): for idx in indices: - xmin, ymin, xmax, ymax = boxes[idx][:] + xmin, ymin, xmax, ymax = boxes[n][idx][:] det_outs.append([c, scores[n][c][idx], xmin, ymin, xmax, ymax]) return det_outs, lod @@ -179,9 +179,9 @@ class TestMulticlassNMSOp(OpTest): scores = np.reshape(scores, (N, M, C)) scores = np.transpose(scores, (0, 2, 1)) - boxes = np.random.random((M, BOX_SIZE)).astype('float32') - boxes[:, 0:2] = boxes[:, 0:2] * 0.5 - boxes[:, 2:4] = boxes[:, 2:4] * 0.5 + 0.5 + boxes = np.random.random((N, M, BOX_SIZE)).astype('float32') + boxes[:, :, 0:2] = boxes[:, :, 0:2] * 0.5 + boxes[:, :, 2:4] = boxes[:, :, 2:4] * 0.5 + 0.5 nmsed_outs, lod = batched_multiclass_nms(boxes, scores, background, score_threshold, nms_threshold, -- GitLab