distribute_fpn_proposals_op.cc 6.0 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
#include "paddle/fluid/framework/op_version_registry.h"
17 18 19 20 21 22 23 24 25

namespace paddle {
namespace operators {

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

  void InferShape(framework::InferShapeContext* ctx) const override {
26 27 28 29 30 31 32 33
    PADDLE_ENFORCE_EQ(
        ctx->HasInput("FpnRois"), true,
        platform::errors::NotFound("Input(FpnRois) of DistributeFpnProposalsOp"
                                   " is not found"));
    PADDLE_ENFORCE_GE(ctx->Outputs("MultiFpnRois").size(), 1UL,
                      platform::errors::InvalidArgument(
                          "Outputs(MultiFpnRois) of "
                          "DistributeFpnProposalsOp should not be empty"));
34 35
    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"));
36 37 38 39 40 41
    PADDLE_ENFORCE_GE(
        max_level, min_level,
        platform::errors::InvalidArgument(
            "max_level must not lower than "
            "min_level. But received max_level = %d, min_level = %d",
            max_level, min_level));
42 43 44 45 46 47 48 49 50
    // 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);
51
    ctx->SetOutputDim("RestoreIndex", {-1, 1});
52 53 54 55 56 57 58 59

    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);
    }
60 61 62 63 64
    if (!ctx->IsRuntime()) {
      for (size_t i = 0; i < num_out_rois; ++i) {
        ctx->SetLoDLevel("MultiFpnRois", ctx->GetLoDLevel("FpnRois"), i);
      }
    }
65 66 67 68 69
  }

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
70
    auto data_type = OperatorWithKernel::IndicateVarDataType(ctx, "FpnRois");
71
    return framework::OpKernelType(data_type, ctx.device_context());
72 73 74 75 76 77
  }
};

class DistributeFpnProposalsOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
78 79 80 81 82
    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();
83 84 85 86 87
    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");
88 89 90 91 92 93
    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();
94 95 96 97 98 99 100 101 102 103 104 105
    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");
106 107 108
    AddAttr<bool>("pixel_offset", "(bool, default True),",
                  "If true, im_shape pixel offset is 1.")
        .SetDefault(true);
109 110 111 112 113 114 115 116 117 118 119 120 121
    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 已提交
122 123 124 125 126
REGISTER_OPERATOR(
    distribute_fpn_proposals, ops::DistributeFpnProposalsOp,
    ops::DistributeFpnProposalsOpMaker,
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>);
127 128 129
REGISTER_OP_CPU_KERNEL(distribute_fpn_proposals,
                       ops::DistributeFpnProposalsOpKernel<float>,
                       ops::DistributeFpnProposalsOpKernel<double>);
130 131 132 133 134 135
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()
136
            .NewInput("RoisNum", "The number of RoIs in each image.")
137 138 139
            .NewOutput("MultiLevelRoisNum",
                       "The RoIs' number of each image on multiple "
                       "levels. The number on each level has the shape of (B),"
140 141 142 143 144
                       "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));