distribute_fpn_proposals_op.cc 6.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.

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. */

#include "paddle/fluid/operators/detection/distribute_fpn_proposals_op.h"
16

17
#include "paddle/fluid/framework/op_version_registry.h"
18 19 20 21 22 23 24 25 26

namespace paddle {
namespace operators {

class DistributeFpnProposalsOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
27
    PADDLE_ENFORCE_EQ(
28 29
        ctx->HasInput("FpnRois"),
        true,
30 31
        platform::errors::NotFound("Input(FpnRois) of DistributeFpnProposalsOp"
                                   " is not found"));
32 33
    PADDLE_ENFORCE_GE(ctx->Outputs("MultiFpnRois").size(),
                      1UL,
34 35 36
                      platform::errors::InvalidArgument(
                          "Outputs(MultiFpnRois) of "
                          "DistributeFpnProposalsOp should not be empty"));
37 38
    size_t min_level = static_cast<size_t>(ctx->Attrs().Get<int>("min_level"));
    size_t max_level = static_cast<size_t>(ctx->Attrs().Get<int>("max_level"));
39
    PADDLE_ENFORCE_GE(
40 41
        max_level,
        min_level,
42 43 44
        platform::errors::InvalidArgument(
            "max_level must not lower than "
            "min_level. But received max_level = %d, min_level = %d",
45 46
            max_level,
            min_level));
47 48 49 50 51 52 53 54 55
    // Set the output shape
    size_t num_out_rois = max_level - min_level + 1;
    std::vector<framework::DDim> outs_dims;
    outs_dims.reserve(num_out_rois);
    for (size_t i = 0; i < num_out_rois; ++i) {
      framework::DDim out_dim = {-1, 4};
      outs_dims.push_back(out_dim);
    }
    ctx->SetOutputsDim("MultiFpnRois", outs_dims);
56
    ctx->SetOutputDim("RestoreIndex", {-1, 1});
57 58 59 60 61 62 63 64

    if (ctx->HasOutputs("MultiLevelRoIsNum")) {
      std::vector<framework::DDim> outs_num_dims;
      for (size_t i = 0; i < num_out_rois; ++i) {
        outs_num_dims.push_back({-1});
      }
      ctx->SetOutputsDim("MultiLevelRoIsNum", outs_num_dims);
    }
65 66 67 68 69
    if (!ctx->IsRuntime()) {
      for (size_t i = 0; i < num_out_rois; ++i) {
        ctx->SetLoDLevel("MultiFpnRois", ctx->GetLoDLevel("FpnRois"), i);
      }
    }
70 71 72 73 74
  }

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
75
    auto data_type = OperatorWithKernel::IndicateVarDataType(ctx, "FpnRois");
76
    return framework::OpKernelType(data_type, ctx.device_context());
77 78 79 80 81 82
  }
};

class DistributeFpnProposalsOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
83 84 85 86 87
    AddInput("FpnRois", "(LoDTensor) The RoIs at all levels in shape (-1, 4)");
    AddInput("RoisNum",
             "(Tensor) The number of RoIs in shape (B),"
             "B is the number of images")
        .AsDispensable();
88 89 90 91 92
    AddOutput("MultiFpnRois", "(LoDTensor) Output with distribute operator")
        .AsDuplicable();
    AddOutput("RestoreIndex",
              "(Tensor) An array of positive number which is "
              "used to restore the order of FpnRois");
93 94 95 96 97 98
    AddOutput("MultiLevelRoIsNum",
              "(List of Tensor) The RoIs' number of each image on multiple "
              "levels. The number on each level has the shape of (B),"
              "B is the number of images.")
        .AsDuplicable()
        .AsDispensable();
99 100 101 102 103 104 105 106 107 108 109 110
    AddAttr<int>("min_level",
                 "The lowest level of FPN layer where the"
                 " proposals come from");
    AddAttr<int>("max_level",
                 "The highest level of FPN layer where the"
                 " proposals come from");
    AddAttr<int>("refer_level",
                 "The referring level of FPN layer with"
                 " specified scale");
    AddAttr<int>("refer_scale",
                 "The referring scale of FPN layer with"
                 " specified level");
111
    AddAttr<bool>("pixel_offset",
112
                  "(bool, default True),"
113 114
                  "If true, im_shape pixel offset is 1.")
        .SetDefault(true);
115 116 117 118 119 120 121 122 123 124 125 126 127
    AddComment(R"DOC(
This operator distribute all proposals into different fpn level,
 with respect to scale of the proposals, the referring scale and
 the referring level. Besides, to restore the order of proposals,
we return an array which indicate the original index of rois in
 current proposals.
)DOC");
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
H
hong 已提交
128
REGISTER_OPERATOR(
129 130
    distribute_fpn_proposals,
    ops::DistributeFpnProposalsOp,
H
hong 已提交
131 132 133
    ops::DistributeFpnProposalsOpMaker,
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>);
134 135 136
REGISTER_OP_CPU_KERNEL(distribute_fpn_proposals,
                       ops::DistributeFpnProposalsOpKernel<float>,
                       ops::DistributeFpnProposalsOpKernel<double>);
137 138 139 140 141 142
REGISTER_OP_VERSION(distribute_fpn_proposals)
    .AddCheckpoint(
        R"ROC(
              Upgrade distribute_fpn_proposals add a new input
              [RoisNum] and add a new output [MultiLevelRoIsNum].)ROC",
        paddle::framework::compatible::OpVersionDesc()
143
            .NewInput("RoisNum", "The number of RoIs in each image.")
144 145 146
            .NewOutput("MultiLevelRoisNum",
                       "The RoIs' number of each image on multiple "
                       "levels. The number on each level has the shape of (B),"
147 148 149 150 151
                       "B is the number of images."))
    .AddCheckpoint(
        R"ROC(Register distribute_fpn_proposals for adding the attribute of pixel_offset)ROC",
        paddle::framework::compatible::OpVersionDesc().NewAttr(
            "pixel_offset", "If true, im_shape pixel offset is 1.", true));