diff --git a/src/common/types.cpp b/src/common/types.cpp index 1611a919ffe716e31ff83b8673035a048ebe96d2..cea42171f0205e0d40b2703d5c90f0b9fc253e68 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -40,6 +40,8 @@ const std::string G_OP_TYPE_SPLIT = "split"; const std::string G_OP_TYPE_FEED = "feed"; const std::string G_OP_TYPE_FETCH = "fetch"; const std::string G_OP_TYPE_DEPTHWISE_CONV = "depthwise_conv2d"; +const std::string G_OP_TYPE_IM2SEQUENCE = "im2sequence"; +const std::string G_OP_TYPE_DROPOUT = "dropout"; std::unordered_map< std::string, std::pair, std::vector>> @@ -66,6 +68,8 @@ std::unordered_map< {G_OP_TYPE_FC, {{"X", "Y", "Z"}, {"Out"}}}, {G_OP_TYPE_RESHAPE, {{"X"}, {"Out"}}}, {G_OP_TYPE_DEPTHWISE_CONV, {{"Input"}, {"Output"}}}, - {G_OP_TYPE_FUSION_CONV_ADD_RELU, {{"Input"}, {"Out"}}}}; + {G_OP_TYPE_FUSION_CONV_ADD_RELU, {{"Input"}, {"Out"}}}, + {G_OP_TYPE_IM2SEQUENCE, {{"X"}, {"Out"}}}, + {G_OP_TYPE_DROPOUT, {{"X"}, {"Out"}}}}; } // namespace paddle_mobile diff --git a/src/common/types.h b/src/common/types.h index 9134ebe3561153e32db157c4c4b835a1bc464149..ec428b9911f64d7ccc8c6f5dc4be7f970e855d3c 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -96,6 +96,8 @@ extern const std::string G_OP_TYPE_SPLIT; extern const std::string G_OP_TYPE_FEED; extern const std::string G_OP_TYPE_FETCH; extern const std::string G_OP_TYPE_DEPTHWISE_CONV; +extern const std::string G_OP_TYPE_IM2SEQUENCE; +extern const std::string G_OP_TYPE_DROPOUT; extern std::unordered_map< std::string, std::pair, std::vector>> diff --git a/src/operators/dropout_op.cpp b/src/operators/dropout_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..709d83a1f57b7faa0ecce1f1f8590c86c1eba1a8 --- /dev/null +++ b/src/operators/dropout_op.cpp @@ -0,0 +1,39 @@ +/* Copyright (c) 2018 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. */ + +#ifdef DROPOUT_OP +#include "operators/dropout_op.h" +namespace paddle_mobile { +namespace operators { + +template +void DropoutOp::InferShape() const { + auto input_dims = this->param_.InputX()->dims(); + this->param_.Out()->Resize(input_dims); +} +template class DropoutOp; +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +USE_OP_CPU(dropout); +REGISTER_OPERATOR_CPU(dropout, ops::DropoutOp); +#endif +#ifdef PADDLE_MOBILE_MALI_GPU +#endif +#ifdef PADDLE_MOBILE_FPGA +#endif + +#endif diff --git a/src/operators/dropout_op.h b/src/operators/dropout_op.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2986b791e9069e8782d778a0f16cb639ac4396 --- /dev/null +++ b/src/operators/dropout_op.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018 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. */ + +#ifdef DROPOUT_OP + +#pragma once + +#include + +#include "framework/operator.h" +#include "operators/kernel/dropout_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +using paddle_mobile::framework::Tensor; + +template +class DropoutOp + : public framework::OperatorWithKernel< + DeviceType, DropoutParam, operators::DropoutKernel> { + public: + DropoutOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel>( + type, inputs, outputs, attrs, scope) {} + + // using framework::OperatorWithKernel>; + void InferShape() const override; + + protected: +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/im2sequence_op.cpp b/src/operators/im2sequence_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cb2d6398f85f461bd6214e2631dd0a8f951fb2d --- /dev/null +++ b/src/operators/im2sequence_op.cpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2018 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. */ + +#ifdef IM2SEQUENCE_OP + +#include "operators/im2sequence_op.h" + +namespace paddle_mobile { +namespace operators { + +int Im2SequenceOutputSize(int input_size, int kernel, int padding_1, + int padding_2, int stride) { + int output_size = + 1 + (padding_1 + padding_2 + input_size - kernel + stride - 1) / stride; + return output_size; +} + +template +void Im2SequenceOp::InferShape() const { + auto in_x_dims = this->param_.Input()->dims(); + + const std::vector &kernels = this->param_.Kernels(); + + const std::vector &strides = this->param_.Strides(); + + std::vector paddings = this->param_.Paddings(); + + std::vector output_shape({in_x_dims[0], in_x_dims[1]}); + for (size_t i = 0; i < strides.size(); ++i) { + output_shape.push_back(Im2SequenceOutputSize(in_x_dims[i + 2], kernels[i], + paddings[i], paddings[i + 2], + strides[i])); + } + + framework::DDim ddim = framework::make_ddim(output_shape); + this->param_.Output()->Resize(ddim); +} + +template class Im2SequenceOp; + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef PADDLE_MOBILE_CPU +USE_OP_CPU(im2sequence); +REGISTER_OPERATOR_CPU(im2sequence, ops::Im2SequenceOp); +#endif +#ifdef PADDLE_MOBILE_MALI_GPU +#endif +#ifdef PADDLE_MOBILE_FPGA +#endif + +#endif diff --git a/src/operators/im2sequence_op.h b/src/operators/im2sequence_op.h new file mode 100644 index 0000000000000000000000000000000000000000..4c4dee617277bcee874d1fcd840c7ddd8fd68cbd --- /dev/null +++ b/src/operators/im2sequence_op.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018 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. */ + +#ifdef IM2SEQUENCE_OP + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/im2sequence_kernel.h" + +namespace paddle_mobile { +namespace operators { + +using namespace framework; + +template +class Im2SequenceOp : public framework::OperatorWithKernel< + DeviceType, Im2SequenceParam, + operators::Im2SequenceKernel> { + public: + Im2SequenceOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + std::shared_ptr scope) + : framework::OperatorWithKernel< + DeviceType, Im2SequenceParam, + operators::Im2SequenceKernel>(type, inputs, outputs, + attrs, scope) {} + + // using framework::OperatorWithKernel< + // DeviceType, Im2SequenceParam, + // operators::Im2SequenceKernel>::OperatorWithKernel; + void InferShape() const override; + + private: +}; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/dropout_kernel.cpp b/src/operators/kernel/arm/dropout_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af16048a1b4eba2ff36f842b6cf968031989576e --- /dev/null +++ b/src/operators/kernel/arm/dropout_kernel.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2018 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. */ + +#ifdef DROPOUT_OP + +#pragma once + +#include "operators/kernel/dropout_kernel.h" +#include + +namespace paddle_mobile { +namespace operators { + +template <> +bool DropoutKernel::Init(DropoutParam *para) { + return true; +} + +template +struct DropoutFunctor { + inline T operator()(T in) const { return in; } +}; + +template <> +void DropoutKernel::Compute(const DropoutParam ¶m) const { + const auto *input_x = param.InputX(); + auto *input_x_ptr = input_x->data(); + auto *out = param.Out(); + auto *out_ptr = out->mutable_data(); + + DropoutFunctor func_; + math::Transform trans; + trans(input_x_ptr, input_x_ptr + input_x->numel(), out_ptr, func_); +} +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/arm/im2sequence_kernel.cpp b/src/operators/kernel/arm/im2sequence_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..709fa30a23d4efba3531d9bc567c99f53875bc12 --- /dev/null +++ b/src/operators/kernel/arm/im2sequence_kernel.cpp @@ -0,0 +1,78 @@ +/* Copyright (c) 2018 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. */ + +#ifdef IM2SEQUENCE_OP + +#include "operators/kernel/im2sequence_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template <> +bool Im2SequenceKernel::Init(Im2SequenceParam *para) { + return true; +} + +inline int Im2SeqOutputSize(int input_size, int filter_size, int padding_0, + int padding_1, int stride) { + const int output_size = + (input_size + padding_0 + padding_1 - filter_size) / stride + 1; + return output_size; +} + +template <> +void Im2SequenceKernel::Compute( + const Im2SequenceParam ¶m) const { + const Tensor *in_x = param.Input(); + Tensor *out = param.Output(); + out->mutable_data(); + + std::vector kernels = param.Kernels(); + std::vector strides = param.Strides(); + std::vector paddings = param.Paddings(); + + auto in_x_dim = in_x->dims(); + const int batch_size = static_cast(in_x_dim[0]); + const int img_channels = static_cast(in_x_dim[1]); + const int img_height = static_cast(in_x_dim[2]); + const int img_width = static_cast(in_x_dim[3]); + + int output_height = Im2SeqOutputSize(img_height, kernels[0], paddings[0], + paddings[2], strides[0]); + int output_width = Im2SeqOutputSize(img_width, kernels[1], paddings[1], + paddings[3], strides[1]); + const std::vector dilations({1, 1}); + + // TODO: verify + auto out_dims = out->dims(); + out->Resize({batch_size, out->numel() / batch_size}); + + for (int i = 0; i < batch_size; i++) { + const Tensor src = + in_x->Slice(i, i + 1).Resize({img_channels, img_height, img_width}); + Tensor dst = out->Slice(i, i + 1).Resize( + {output_height, output_width, img_channels, kernels[0], kernels[1]}); + + math::Im2ColFunctor f; + f(src, dilations, strides, paddings, &dst); + } + out->Resize(out_dims); +} + +template class Im2SequenceKernel; + +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/dropout_kernel.h b/src/operators/kernel/dropout_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..5a3783971959db8fba9ca6b701fb6eb6340fcb3f --- /dev/null +++ b/src/operators/kernel/dropout_kernel.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018 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. */ + +#ifdef DROPOUT_OP + +#include "framework/operator.h" +#include "operators/op_param.h" + +#pragma once; + +namespace paddle_mobile { +namespace operators { + +template +class DropoutKernel : public framework::OpKernelBase { + public: + void Compute(const DropoutParam& param) const; + bool Init(DropoutParam* para); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/kernel/im2sequence_kernel.h b/src/operators/kernel/im2sequence_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..cb592613f73d90dae5a7d6e515f8bc091981776e --- /dev/null +++ b/src/operators/kernel/im2sequence_kernel.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2018 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. */ + +#ifdef IM2SEQUENCE_OP + +#include "framework/operator.h" +#include "operators/math/im2col.h" +#include "operators/math/math_function.h" +#include "operators/math/vol2col.h" +#include "operators/op_param.h" + +#pragma once; + +namespace paddle_mobile { +namespace operators { + +using namespace framework; + +template +class Im2SequenceKernel + : public framework::OpKernelBase { + public: + void Compute(const Im2SequenceParam& param) const; + bool Init(Im2SequenceParam* para); +}; +} // namespace operators +} // namespace paddle_mobile + +#endif diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 229779a127a8dc828da1a1c7ccb3ffe188073f47..c0f0fbc8a9939bc4609e64359835a685dd4c67f9 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -934,5 +934,57 @@ class FusionConvAddBNReluParam : public OpParam { Print &operator<<(Print &printer, const FusionConvAddParam &conv_param); #endif + +#ifdef IM2SEQUENCE_OP +class Im2SequenceParam : public OpParam { + public: + Im2SequenceParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + kernels_ = GetAttr>("kernels", attrs); + strides_ = GetAttr>("strides", attrs); + paddings_ = GetAttr>("paddings", attrs); + } + + const Tensor *Input() const { return input_x_; } + + Tensor *Output() const { return out_; } + + const vector &Kernels() const { return kernels_; } + + const vector &Strides() const { return strides_; } + + const vector &Paddings() const { return paddings_; } + + private: + Tensor *input_x_; + Tensor *out_; + vector kernels_; + vector strides_; + vector paddings_; +}; +#endif + +#ifdef DROPOUT_OP +class DropoutParam : public OpParam { + public: + DropoutParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + } + + const Tensor *InputX() const { return input_x_; } + + Tensor *Out() const { return out_; } + + private: + Tensor *input_x_; + Tensor *out_; +}; +#endif + } // namespace operators } // namespace paddle_mobile diff --git a/test/operators/test_im2sequence_op.cpp b/test/operators/test_im2sequence_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7512d3bf3cffcb100fe292e50fc7b7b23fa0aa0 --- /dev/null +++ b/test/operators/test_im2sequence_op.cpp @@ -0,0 +1,62 @@ +/* Copyright (c) 2018 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 "../executor_for_test.h" +#include "../test_include.h" +#include "operators/im2sequence_op.h" + +int main() { + paddle_mobile::Loader loader; + auto program = loader.Load(g_ocr_recg); + PADDLE_MOBILE_ENFORCE(program.originProgram != nullptr, + "program file read fail"); + + Executor4Test> + executor(program, "im2sequence"); + + // 1. input_tensors; + vector input_tensors; + + Tensor input1; + auto input1_data = CreateInput(&input1, {2, 2, 3, 3}, -1, 1); + input_tensors.push_back(input1); + + // 2. input_names + vector input_names({ + "conv2d_19.tmp_1", + }); + + // 3. output_names + vector output_names({"im2sequence_0.tmp_0"}); + + // 4. out_dims; + vector out_ddims; + auto out_ddim = paddle_mobile::framework::make_ddim({8, 9}); + out_ddims.push_back(out_ddim); + + auto output = executor.Predict(input_tensors, input_names, + output_names, out_ddims); + + auto output0_data = output[0]->data(); + + for (int j = 0; j < input_tensors[0].numel(); ++j) { + DLOG << " value of input: " << input1_data[j]; + } + + for (int j = 0; j < output[0]->numel(); ++j) { + DLOG << " value of output: " << output0_data[j]; + } + return 0; +} diff --git a/tools/op.cmake b/tools/op.cmake index c7d1840bc552d6b45fe2fcc9f8d19e6784598ee6..8ddf739b5fc112ba0fa588d4d5b354ceaeb8ebde 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -66,7 +66,8 @@ else () set(TRANSPOSE_OP ON) set(FUSION_CONVADD_RELU_OP ON) set(FUSION_CONVADDBNRELU_OP ON) - + set(DROPOUT_OP ON) + set(IM2SEQUENCE_OP ON) # option(BATCHNORM_OP "" ON) # option(BOXCODER_OP "" ON) # option(CONCAT_OP "" ON) @@ -152,3 +153,9 @@ endif() if (FUSION_CONVADDBNRELU_OP) add_definitions(-DFUSION_CONVADDBNRELU_OP) endif() +if (DROPOUT_OP) + add_definitions(-DDROPOUT_OP) +endif() +if (IM2SEQUENCE_OP) + add_definitions(-DIM2SEQUENCE_OP) +endif()