提交 bf34a8b8 编写于 作者: Y yaokun01

add im2sequence op

上级 8a83b005
/* 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 "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 <typename Dtype, typename T>
void Im2SequenceOp<Dtype, T>::InferShape() const {
auto in_dims = param_.Input()->dims();
const std::vector<int> &kernels = param_.Kernels();
const std::vector<int> &strides = param_.Strides();
std::vector<int> paddings = param_.Paddings();
std::vector<int64_t> output_shape({in_dims[0], in_dims[0]});
for (size_t i = 0; i < strides.size(); ++i) {
output_shape.push_back(Im2SequenceOutputSize(in_dims[i + 2], kernels[i],
paddings[i], paddings[i + 2],
strides[i]));
}
framework::DDim ddim = framework::make_ddim(output_shape);
param_.Output()->Resize(ddim);
}
template class Im2SequenceOp<CPU, float>;
} // namespace operators
} // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(im2sequence);
REGISTER_OPERATOR(im2sequence, ops::Im2SequenceOp);
/* 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. */
#pragma once
#include "framework/operator.h"
#include "operators/kernel/im2sequence_kernel.h"
#include <operators/op_param.h>
namespace paddle_mobile {
namespace operators {
using namespace framework;
template <typename DeviceType, typename T>
class Im2SequenceOp : public framework::OperatorWithKernel<DeviceType> {
public:
Im2SequenceOp(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &outputs, const framework::AttributeMap &attrs,
std::shared_ptr<framework::Scope> scope)
: framework::OperatorWithKernel<DeviceType>(type, inputs, outputs, attrs,
scope),
param_(inputs, outputs, attrs, *scope) {}
using framework::OperatorWithKernel<DeviceType>::OperatorWithKernel;
void InferShape() const override;
void RunImpl() const {
operators::Im2SequenceKernel<DeviceType, T> kernel;
kernel.Compute(param_);
this->ClearVariables({"Input"});
}
private:
Im2SequenceParam param_;
};
} // namespace operators
} // namespace paddle_mobile
/* 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 "operators/kernel/im2sequence_kernel.h"
namespace paddle_mobile {
namespace operators {
bool IsExpand(const std::vector<int> &kernels,
const std::vector<int> &strides,
const std::vector<int> &paddings) {
bool kernels_1 = true, strides_1 = true, padding_0 = true;
for (size_t j = 0; j < strides.size(); ++j) {
kernels_1 = kernels_1 && (kernels[j] == 1);
strides_1 = strides_1 && (strides[j] == 1);
padding_0 = padding_0 && (paddings[j] == 0);
}
return !(kernels_1 && strides_1 && padding_0);
}
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<CPU, float>::Compute(const Im2SequenceParam &param) const {
//LOG(kLOG_DEBUG) << param;
const Tensor *input = param.Input();
Tensor *output = param.Output();
output->mutable_data<float>();
std::vector<int> kernels = param.Kernels();
std::vector<int> strides = param.Strides();
std::vector<int> paddings = param.Paddings();
auto in_dim = input->dims();
const int batch_size = static_cast<int>(in_dim[0]);
const int img_channels = static_cast<int>(in_dim[1]);
const int img_height = static_cast<int>(in_dim[2]);
const int img_width = static_cast<int>(in_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<int> dilations({1, 1});
//TODO: verify
auto out_dims = output->dims();
output->Resize({batch_size, output->numel() / batch_size});
for (int i = 0; i < batch_size; i++) {
const Tensor src =
input->Slice(i, i + 1).Resize({img_channels, img_height, img_width});
Tensor dst = output->Slice(i, i + 1).Resize(
{output_height, output_width, img_channels, kernels[0], kernels[1]});
math::Im2ColFunctor<math::ColFormat::kOCF, CPU, float> f;
f(src, dilations, strides, paddings, &dst);
}
output->Resize(out_dims);
}
template class Im2SequenceKernel<CPU, float>;
} // namespace operators
} // namespace paddle_mobile
/* 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 "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 <typename DeviceType, typename T>
class Im2SequenceKernel : public framework::OpKernelBase<DeviceType, Im2SequenceParam> {
public:
void Compute(const Im2SequenceParam &param) const;
};
} // namespace operators
} // namespace paddle_mobile
......@@ -752,5 +752,34 @@ class FushionFcParam : public OpParam {
int axis_;
};
class Im2SequenceParam : public OpParam {
public:
Im2SequenceParam(const VariableNameMap &inputs, const VariableNameMap &outputs,
const AttributeMap &attrs, const Scope &scope) {
input_ = InputFrom<LoDTensor>(inputs, scope);
output_ = OutputFrom<LoDTensor>(outputs, scope);
kernels_ = GetAttr<vector<int>>("kernels", attrs);
strides_ = GetAttr<vector<int>>("strides", attrs);
paddings_ = GetAttr<vector<int>>("paddings", attrs);
}
const Tensor *Input() const { return input_; }
Tensor *Output() const { return output_; }
const vector<int> &Kernels() const { return kernels_; }
const vector<int> &Strides() const { return strides_; }
const vector<int> &Paddings() const { return paddings_; }
private:
Tensor *input_;
Tensor *output_;
vector<int> kernels_;
vector<int> strides_;
vector<int> paddings_;
};
} // namespace operators
} // namespace paddle_mobile
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册