prior_box_op.cc 10.7 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 39 40 41

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

class PriorBoxOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
Y
Yu Yang 已提交
69
  void Make() override {
W
wanghaox 已提交
70
    AddInput("Input",
W
wanghaox 已提交
71
             "(Tensor, default Tensor<float>), "
W
wanghaox 已提交
72
             "the input feature data of PriorBoxOp, The layout is NCHW.");
W
wanghaox 已提交
73
    AddInput("Image",
W
wanghaox 已提交
74
             "(Tensor, default Tensor<float>), "
W
wanghaox 已提交
75
             "the input image data of PriorBoxOp, The layout is NCHW.");
W
wanghaox 已提交
76
    AddOutput("Boxes",
W
wanghaox 已提交
77
              "(Tensor, default Tensor<float>), the output prior boxes of "
W
wanghaox 已提交
78 79 80
              "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 已提交
81 82
    AddOutput("Variances",
              "(Tensor, default Tensor<float>), the expanded variances of "
W
wanghaox 已提交
83 84 85
              "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 已提交
86

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

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

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

W
wanghaox 已提交
164 165 166 167
    AddAttr<float>("offset",
                   "(float) "
                   "Prior boxes center offset.")
        .SetDefault(0.5);
168 169 170 171 172 173 174
    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);
175 176 177
    AddAttr<bool>("use_mkldnn",
                  "(bool, default false) Only used in mkldnn kernel")
        .SetDefault(false);
178 179 180 181
    AddAttr<bool>(
        "use_quantizer",
        "(bool, default false) "
        "This parameter is no longer used. Use 'mkldnn_data_type' instead.")
182
        .SetDefault(false);
183 184 185 186 187
    AddAttr<std::string>(
        "mkldnn_data_type",
        "(string, default \"float32\"). Data type of mkldnn kernel")
        .SetDefault("float32")
        .InEnum({"float32", "int8", "bfloat16"});
W
wanghaox 已提交
188 189 190
    AddComment(R"DOC(
Prior box operator
Generate prior boxes for SSD(Single Shot MultiBox Detector) algorithm.
W
wanghaox 已提交
191 192 193 194 195
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 已提交
196 197 198 199 200 201 202 203 204
Please get more information from the following papers:
https://arxiv.org/abs/1512.02325.
)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

Z
zhiboniu 已提交
205 206 207 208
DECLARE_INFER_SHAPE_FUNCTOR(prior_box,
                            PriorBoxInferShapeFunctor,
                            PD_INFER_META(phi::PriorBoxInferMeta));

W
wanghaox 已提交
209
namespace ops = paddle::operators;
H
hong 已提交
210
REGISTER_OPERATOR(
211 212 213
    prior_box,
    ops::PriorBoxOp,
    ops::PriorBoxOpMaker,
H
hong 已提交
214
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
Z
zhiboniu 已提交
215 216
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>,
    PriorBoxInferShapeFunctor);
217

218 219 220 221
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    FF,
222 223 224
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<float, float>);

225 226 227 228
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    DD,
229 230 231
                                    ops::kPriorBoxDOUBLE,
                                    ops::PriorBoxOpKernel<double, double>);

232 233 234 235
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    U8F,
236 237 238
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<uint8_t, float>);

239 240 241 242
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    S8F,
243 244 245
                                    ops::kPriorBoxFLOAT,
                                    ops::PriorBoxOpKernel<int8_t, float>);

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

253 254 255 256
REGISTER_OP_KERNEL_WITH_CUSTOM_TYPE(prior_box,
                                    MKLDNN,
                                    ::paddle::platform::CPUPlace,
                                    S8D,
257 258
                                    ops::kPriorBoxDOUBLE,
                                    ops::PriorBoxOpKernel<int8_t, double>);