Skip to content

Commit 9557cc2

Browse files
authored
Refine and fix some code for faster-rcnn. (#13135)
* Fix bug in generate_proposals_op. * Fix data type for RoIs. * Refine and fix rpn_target_assign_op. * Add the missing file bbox_util.h * Rename BoxEncoder to BoxToDelta
1 parent d9c3123 commit 9557cc2

File tree

11 files changed

+388
-225
lines changed

11 files changed

+388
-225
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
Licensed under the Apache License, Version 2.0 (the "License");
3+
you may not use this file except in compliance with the License.
4+
You may obtain a copy of the License at
5+
http://www.apache.org/licenses/LICENSE-2.0
6+
Unless required by applicable law or agreed to in writing, software
7+
distributed under the License is distributed on an "AS IS" BASIS,
8+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
See the License for the specific language governing permissions and
10+
limitations under the License. */
11+
#pragma once
12+
#include "paddle/fluid/framework/eigen.h"
13+
#include "paddle/fluid/framework/tensor.h"
14+
15+
namespace paddle {
16+
namespace operators {
17+
18+
/*
19+
* transform that computes target bounding-box regression deltas
20+
* given proposal boxes and ground-truth boxes.
21+
*/
22+
template <typename T>
23+
inline void BoxToDelta(const int box_num, const framework::Tensor& ex_boxes,
24+
const framework::Tensor& gt_boxes, const T* weights,
25+
const bool normalized, framework::Tensor* box_delta) {
26+
auto ex_boxes_et = framework::EigenTensor<T, 2>::From(ex_boxes);
27+
auto gt_boxes_et = framework::EigenTensor<T, 2>::From(gt_boxes);
28+
auto trg = framework::EigenTensor<T, 2>::From(*box_delta);
29+
T ex_w, ex_h, ex_ctr_x, ex_ctr_y, gt_w, gt_h, gt_ctr_x, gt_ctr_y;
30+
for (int64_t i = 0; i < box_num; ++i) {
31+
ex_w = ex_boxes_et(i, 2) - ex_boxes_et(i, 0) + (normalized == false);
32+
ex_h = ex_boxes_et(i, 3) - ex_boxes_et(i, 1) + (normalized == false);
33+
ex_ctr_x = ex_boxes_et(i, 0) + 0.5 * ex_w;
34+
ex_ctr_y = ex_boxes_et(i, 1) + 0.5 * ex_h;
35+
36+
gt_w = gt_boxes_et(i, 2) - gt_boxes_et(i, 0) + (normalized == false);
37+
gt_h = gt_boxes_et(i, 3) - gt_boxes_et(i, 1) + (normalized == false);
38+
gt_ctr_x = gt_boxes_et(i, 0) + 0.5 * gt_w;
39+
gt_ctr_y = gt_boxes_et(i, 1) + 0.5 * gt_h;
40+
41+
trg(i, 0) = (gt_ctr_x - ex_ctr_x) / ex_w;
42+
trg(i, 1) = (gt_ctr_y - ex_ctr_y) / ex_h;
43+
trg(i, 2) = std::log(gt_w / ex_w);
44+
trg(i, 3) = std::log(gt_h / ex_h);
45+
46+
if (weights) {
47+
trg(i, 0) = trg(i, 0) / weights[0];
48+
trg(i, 1) = trg(i, 1) / weights[1];
49+
trg(i, 2) = trg(i, 2) / weights[2];
50+
trg(i, 3) = trg(i, 3) / weights[3];
51+
}
52+
}
53+
}
54+
55+
template <typename T>
56+
void Gather(const T* in, const int in_stride, const int* index, const int num,
57+
T* out) {
58+
const int stride_bytes = in_stride * sizeof(T);
59+
for (int i = 0; i < num; ++i) {
60+
int id = index[i];
61+
memcpy(out + i * in_stride, in + id * in_stride, stride_bytes);
62+
}
63+
}
64+
65+
} // namespace operators
66+
} // namespace paddle

paddle/fluid/operators/detection/generate_proposal_labels_op.cc

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ limitations under the License. */
1414
#include <string>
1515
#include <vector>
1616
#include "paddle/fluid/framework/op_registry.h"
17+
#include "paddle/fluid/operators/detection/bbox_util.h"
1718
#include "paddle/fluid/operators/gather.h"
1819
#include "paddle/fluid/operators/math/concat.h"
1920
#include "paddle/fluid/operators/math/math_function.h"
@@ -133,31 +134,6 @@ void BboxOverlaps(const Tensor& r_boxes, const Tensor& c_boxes,
133134
}
134135
}
135136

136-
template <typename T>
137-
void BoxToDelta(int box_num, const Tensor& ex_boxes, const Tensor& gt_boxes,
138-
const std::vector<float>& weights, Tensor* box_delta) {
139-
auto ex_boxes_et = framework::EigenTensor<T, 2>::From(ex_boxes);
140-
auto gt_boxes_et = framework::EigenTensor<T, 2>::From(gt_boxes);
141-
auto box_delta_et = framework::EigenTensor<T, 2>::From(*box_delta);
142-
T ex_w, ex_h, ex_ctr_x, ex_ctr_y, gt_w, gt_h, gt_ctr_x, gt_ctr_y;
143-
for (int64_t i = 0; i < box_num; ++i) {
144-
ex_w = ex_boxes_et(i, 2) - ex_boxes_et(i, 0) + 1;
145-
ex_h = ex_boxes_et(i, 3) - ex_boxes_et(i, 1) + 1;
146-
ex_ctr_x = ex_boxes_et(i, 0) + 0.5 * ex_w;
147-
ex_ctr_y = ex_boxes_et(i, 1) + 0.5 * ex_h;
148-
149-
gt_w = gt_boxes_et(i, 2) - gt_boxes_et(i, 0) + 1;
150-
gt_h = gt_boxes_et(i, 3) - gt_boxes_et(i, 1) + 1;
151-
gt_ctr_x = gt_boxes_et(i, 0) + 0.5 * gt_w;
152-
gt_ctr_y = gt_boxes_et(i, 1) + 0.5 * gt_h;
153-
154-
box_delta_et(i, 0) = (gt_ctr_x - ex_ctr_x) / ex_w / weights[0];
155-
box_delta_et(i, 1) = (gt_ctr_y - ex_ctr_y) / ex_h / weights[1];
156-
box_delta_et(i, 2) = log(gt_w / ex_w) / ex_w / weights[2];
157-
box_delta_et(i, 3) = log(gt_h / ex_h) / ex_h / weights[3];
158-
}
159-
}
160-
161137
template <typename T>
162138
std::vector<std::vector<int>> SampleFgBgGt(
163139
const platform::CPUDeviceContext& context, Tensor* iou,
@@ -243,12 +219,11 @@ void GatherBoxesLabels(const platform::CPUDeviceContext& context,
243219
Tensor* sampled_labels, Tensor* sampled_gts) {
244220
int fg_num = fg_inds.size();
245221
int bg_num = bg_inds.size();
246-
int gt_num = fg_num + bg_num;
247222
Tensor fg_inds_t, bg_inds_t, gt_box_inds_t, gt_label_inds_t;
248223
int* fg_inds_data = fg_inds_t.mutable_data<int>({fg_num}, context.GetPlace());
249224
int* bg_inds_data = bg_inds_t.mutable_data<int>({bg_num}, context.GetPlace());
250225
int* gt_box_inds_data =
251-
gt_box_inds_t.mutable_data<int>({gt_num}, context.GetPlace());
226+
gt_box_inds_t.mutable_data<int>({fg_num}, context.GetPlace());
252227
int* gt_label_inds_data =
253228
gt_label_inds_t.mutable_data<int>({fg_num}, context.GetPlace());
254229
std::copy(fg_inds.begin(), fg_inds.end(), fg_inds_data);
@@ -303,18 +278,20 @@ std::vector<Tensor> SampleRoisForOneImage(
303278

304279
// Gather boxes and labels
305280
Tensor sampled_boxes, sampled_labels, sampled_gts;
306-
int boxes_num = fg_inds.size() + bg_inds.size();
281+
int fg_num = fg_inds.size();
282+
int bg_num = bg_inds.size();
283+
int boxes_num = fg_num + bg_num;
307284
framework::DDim bbox_dim({boxes_num, kBoxDim});
308285
sampled_boxes.mutable_data<T>(bbox_dim, context.GetPlace());
309286
sampled_labels.mutable_data<int>({boxes_num}, context.GetPlace());
310-
sampled_gts.mutable_data<T>(bbox_dim, context.GetPlace());
287+
sampled_gts.mutable_data<T>({fg_num, kBoxDim}, context.GetPlace());
311288
GatherBoxesLabels<T>(context, boxes, *gt_boxes, *gt_classes, fg_inds, bg_inds,
312289
gt_inds, &sampled_boxes, &sampled_labels, &sampled_gts);
313290

314291
// Compute targets
315292
Tensor bbox_targets_single;
316293
bbox_targets_single.mutable_data<T>(bbox_dim, context.GetPlace());
317-
BoxToDelta<T>(boxes_num, sampled_boxes, sampled_gts, bbox_reg_weights,
294+
BoxToDelta<T>(fg_num, sampled_boxes, sampled_gts, nullptr, false,
318295
&bbox_targets_single);
319296

320297
// Scale rois
@@ -427,7 +404,7 @@ class GenerateProposalLabelsKernel : public framework::OpKernel<T> {
427404
auto rpn_rois_lod = rpn_rois->lod().back();
428405
auto gt_classes_lod = gt_classes->lod().back();
429406
auto gt_boxes_lod = gt_boxes->lod().back();
430-
for (size_t i = 0; i < n; ++i) {
407+
for (int i = 0; i < n; ++i) {
431408
Tensor rpn_rois_slice =
432409
rpn_rois->Slice(rpn_rois_lod[i], rpn_rois_lod[i + 1]);
433410
Tensor gt_classes_slice =

paddle/fluid/operators/detection/generate_proposals_op.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,7 @@ class GenerateProposalsKernel : public framework::OpKernel<T> {
311311

312312
rpn_rois->mutable_data<T>({bbox_deltas->numel() / 4, 4},
313313
context.GetPlace());
314-
rpn_roi_probs->mutable_data<T>({scores->numel() / 4, 1},
315-
context.GetPlace());
314+
rpn_roi_probs->mutable_data<T>({scores->numel(), 1}, context.GetPlace());
316315

317316
Tensor bbox_deltas_swap, scores_swap;
318317
bbox_deltas_swap.mutable_data<T>({num, h_bbox, w_bbox, c_bbox},
@@ -421,7 +420,7 @@ class GenerateProposalsKernel : public framework::OpKernel<T> {
421420
CPUGather<T>(ctx, proposals, keep, &bbox_sel);
422421
CPUGather<T>(ctx, scores_sel, keep, &scores_filter);
423422
if (nms_thresh <= 0) {
424-
return std::make_pair(bbox_sel, scores_sel);
423+
return std::make_pair(bbox_sel, scores_filter);
425424
}
426425

427426
Tensor keep_nms = NMS<T>(ctx, &bbox_sel, &scores_filter, nms_thresh, eta);

0 commit comments

Comments
 (0)