prior_box_op.cc 10.5 KB
Newer Older
1
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
W
wanghaox 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14

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

B
baiyf 已提交
15
#include "paddle/fluid/operators/detection/prior_box_op.h"
16
#include <string>
Z
zhiboniu 已提交
17 18
#include "paddle/fluid/framework/infershape_utils.h"
#include "paddle/phi/infermeta/binary.h"
19

20 21 22
#ifdef PADDLE_WITH_MKLDNN
#include "paddle/fluid/platform/mkldnn_helper.h"
#endif
23
#include "paddle/fluid/framework/convert_utils.h"
24

W
wanghaox 已提交
25 26 27 28 29 30 31
namespace paddle {
namespace operators {

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

32 33 34
 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
35 36
    auto input_input_type =
        OperatorWithKernel::IndicateVarDataType(ctx, "Input");
37 38

#ifdef PADDLE_WITH_MKLDNN
J
jiahongyu 已提交
39
    if (this->CanMKLDNNBeUsed(ctx, input_input_type)) {
40 41
      auto input_image_type = framework::TransToProtoVarType(
          ctx.Input<framework::Tensor>("Image")->dtype());
42 43
      int customized_type_value =
          framework::OpKernelType::kDefaultCustomizedTypeValue;
44
      if (input_image_type == framework::DataTypeTrait<float>::DataType()) {
45 46
        customized_type_value = kPriorBoxFLOAT;
      } else if (input_image_type ==
47
                 framework::DataTypeTrait<double>::DataType()) {
48 49
        customized_type_value = kPriorBoxDOUBLE;
      }
50 51
      return framework::OpKernelType(input_input_type,
                                     ctx.GetPlace(),
J
jiahongyu 已提交
52 53
                                     framework::DataLayout::kMKLDNN,
                                     framework::LibraryType::kMKLDNN,
54
                                     customized_type_value);
55 56
    }
#endif
J
jiahongyu 已提交
57
    return framework::OpKernelType(input_input_type, ctx.GetPlace());
58
  }
W
wanghaox 已提交
59 60 61 62
};

class PriorBoxOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
Y
Yu Yang 已提交
63
  void Make() override {
W
wanghaox 已提交
64
    AddInput("Input",
W
wanghaox 已提交
65
             "(Tensor, default Tensor<float>), "
W
wanghaox 已提交
66
             "the input feature data of PriorBoxOp, The layout is NCHW.");
W
wanghaox 已提交
67
    AddInput("Image",
W
wanghaox 已提交
68
             "(Tensor, default Tensor<float>), "
W
wanghaox 已提交
69
             "the input image data of PriorBoxOp, The layout is NCHW.");
W
wanghaox 已提交
70
    AddOutput("Boxes",
W
wanghaox 已提交
71
              "(Tensor, default Tensor<float>), the output prior boxes of "
W
wanghaox 已提交
72 73 74
              "PriorBoxOp. The layout is [H, W, num_priors, 4]. "
              "H is the height of input, W is the width of input, num_priors "
              "is the box count of each position.");
W
wanghaox 已提交
75 76
    AddOutput("Variances",
              "(Tensor, default Tensor<float>), the expanded variances of "
W
wanghaox 已提交
77 78 79
              "PriorBoxOp. The layout is [H, W, num_priors, 4]. "
              "H is the height of input, W is the width of input, num_priors "
              "is the box count of each position.");
C
fix bug  
chengduoZH 已提交
80

C
chengduoZH 已提交
81 82 83 84
    AddAttr<std::vector<float>>("min_sizes",
                                "(vector<float>) List of min sizes "
                                "of generated prior boxes.")
        .AddCustomChecker([](const std::vector<float>& min_sizes) {
85
          PADDLE_ENFORCE_GT(
86 87
              min_sizes.size(),
              0,
88 89
              platform::errors::InvalidArgument("Size of min_sizes must be "
                                                "at least 1."));
C
fix bug  
chengduoZH 已提交
90
          for (size_t i = 0; i < min_sizes.size(); ++i) {
91 92
            PADDLE_ENFORCE_GT(min_sizes[i],
                              0.0,
93 94 95
                              platform::errors::OutOfRange(
                                  "min_sizes[%d] must be larger "
                                  "than 0. But received: min_sizes[%d] is %f.",
96 97 98
                                  i,
                                  i,
                                  min_sizes[i]));
C
fix bug  
chengduoZH 已提交
99 100
          }
        });
C
chengduoZH 已提交
101
    AddAttr<std::vector<float>>(
C
fix bug  
chengduoZH 已提交
102
        "max_sizes",
103 104
        "(vector<float>) List of max sizes of generated prior boxes.")
        .SetDefault(std::vector<float>{});
W
wanghaox 已提交
105
    AddAttr<std::vector<float>>(
C
fix bug  
chengduoZH 已提交
106 107 108
        "aspect_ratios",
        "(vector<float>) List of aspect ratios of generated prior boxes.");

W
wanghaox 已提交
109
    AddAttr<std::vector<float>>(
C
fix bug  
chengduoZH 已提交
110 111 112
        "variances",
        "(vector<float>) List of variances to be encoded in prior boxes.")
        .AddCustomChecker([](const std::vector<float>& variances) {
113 114
          PADDLE_ENFORCE_EQ(variances.size(),
                            4,
115 116 117 118
                            platform::errors::InvalidArgument(
                                "The length of variance must "
                                "be 4. But received: variances' length is %d.",
                                variances.size()));
C
fix bug  
chengduoZH 已提交
119
          for (size_t i = 0; i < variances.size(); ++i) {
120 121
            PADDLE_ENFORCE_GT(variances[i],
                              0.0,
122 123 124
                              platform::errors::OutOfRange(
                                  "variance[%d] must be greater "
                                  "than 0. But received: variance[%d] = %f",
125 126 127
                                  i,
                                  i,
                                  variances[i]));
C
fix bug  
chengduoZH 已提交
128 129 130
          }
        });
    AddAttr<bool>("flip", "(bool) Whether to flip aspect ratios.")
W
wanghaox 已提交
131
        .SetDefault(true);
C
fix bug  
chengduoZH 已提交
132
    AddAttr<bool>("clip", "(bool) Whether to clip out-of-boundary boxes.")
W
wanghaox 已提交
133
        .SetDefault(true);
C
fix bug  
chengduoZH 已提交
134

W
wanghaox 已提交
135
    AddAttr<float>("step_w",
C
chengduoZH 已提交
136
                   "Prior boxes step across width, 0.0 for auto calculation.")
C
fix bug  
chengduoZH 已提交
137 138
        .SetDefault(0.0)
        .AddCustomChecker([](const float& step_w) {
139 140
          PADDLE_ENFORCE_GE(step_w,
                            0.0,
141 142 143 144
                            platform::errors::InvalidArgument(
                                "step_w should be larger "
                                "than 0. But received: step_w = %f.",
                                step_w));
C
fix bug  
chengduoZH 已提交
145
        });
W
wanghaox 已提交
146
    AddAttr<float>("step_h",
C
chengduoZH 已提交
147
                   "Prior boxes step across height, 0.0 for auto calculation.")
C
fix bug  
chengduoZH 已提交
148 149
        .SetDefault(0.0)
        .AddCustomChecker([](const float& step_h) {
150 151
          PADDLE_ENFORCE_GE(step_h,
                            0.0,
152 153 154 155
                            platform::errors::InvalidArgument(
                                "step_h should be larger "
                                "than 0. But received: step_h = %f.",
                                step_h));
C
fix bug  
chengduoZH 已提交
156 157
        });

W
wanghaox 已提交
158 159 160 161
    AddAttr<float>("offset",
                   "(float) "
                   "Prior boxes center offset.")
        .SetDefault(0.5);
162 163 164 165 166 167 168
    AddAttr<bool>(
        "min_max_aspect_ratios_order",
        "(bool) If set True, the output prior box is in order of"
        "[min, max, aspect_ratios], which is consistent with Caffe."
        "Please note, this order affects the weights order of convolution layer"
        "followed by and does not affect the final detection results.")
        .SetDefault(false);
169 170 171
    AddAttr<bool>("use_mkldnn",
                  "(bool, default false) Only used in mkldnn kernel")
        .SetDefault(false);
172 173 174 175
    AddAttr<bool>(
        "use_quantizer",
        "(bool, default false) "
        "This parameter is no longer used. Use 'mkldnn_data_type' instead.")
176
        .SetDefault(false);
177 178 179 180 181
    AddAttr<std::string>(
        "mkldnn_data_type",
        "(string, default \"float32\"). Data type of mkldnn kernel")
        .SetDefault("float32")
        .InEnum({"float32", "int8", "bfloat16"});
W
wanghaox 已提交
182 183 184
    AddComment(R"DOC(
Prior box operator
Generate prior boxes for SSD(Single Shot MultiBox Detector) algorithm.
W
wanghaox 已提交
185 186 187 188 189
Each position of the input produce N prior boxes, N is determined by
 the count of min_sizes, max_sizes and aspect_ratios, The size of the
 box is in range(min_size, max_size) interval, which is generated in
 sequence according to the aspect_ratios.

W
wanghaox 已提交
190 191 192 193 194 195 196 197 198
Please get more information from the following papers:
https://arxiv.org/abs/1512.02325.
)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

Z
zhiboniu 已提交
199 200 201 202
DECLARE_INFER_SHAPE_FUNCTOR(prior_box,
                            PriorBoxInferShapeFunctor,
                            PD_INFER_META(phi::PriorBoxInferMeta));

W
wanghaox 已提交
203
namespace ops = paddle::operators;
H
hong 已提交
204
REGISTER_OPERATOR(
205 206 207
    prior_box,
    ops::PriorBoxOp,
    ops::PriorBoxOpMaker,
H
hong 已提交
208
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
Z
zhiboniu 已提交
209 210
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>,
    PriorBoxInferShapeFunctor);
211

212 213 214 215
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    FF,
216 217 218
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<float, float>);

219 220 221 222
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    DD,
223 224 225
                                    ops::kPriorBoxDOUBLE,
                                    ops::PriorBoxOpKernel<double, double>);

226 227 228 229
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    U8F,
230 231 232
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<uint8_t, float>);

233 234 235 236
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    S8F,
237 238 239
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<int8_t, float>);

240 241 242 243
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    U8D,
244 245 246
                                    ops::kPriorBoxDOUBLE,
                                    ops::PriorBoxOpKernel<uint8_t, double>);

247 248 249 250
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    S8D,
251 252
                                    ops::kPriorBoxDOUBLE,
                                    ops::PriorBoxOpKernel<int8_t, double>);