From 36e6afa5676fad12e1bf4fa86202305178bfa07d Mon Sep 17 00:00:00 2001 From: Antkillerfarm Date: Thu, 13 Jan 2022 14:17:19 +0800 Subject: [PATCH] add alpha & beta parameters for HardSigmoid (#265) --- include/tim/vx/ops/activations.h | 12 ++++- .../ops/activation_layout_inference.h | 27 +--------- src/tim/vx/ops/activations.cc | 11 +++- src/tim/vx/ops/activations_test.cc | 52 ++++++++++++++++++- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/include/tim/vx/ops/activations.h b/include/tim/vx/ops/activations.h index 3911493..0f2070d 100644 --- a/include/tim/vx/ops/activations.h +++ b/include/tim/vx/ops/activations.h @@ -85,7 +85,6 @@ DECLARE_NO_PARAMETER_ACTIVATION(Sigmoid) DECLARE_NO_PARAMETER_ACTIVATION(Swish) DECLARE_NO_PARAMETER_ACTIVATION(HardSwish) DECLARE_NO_PARAMETER_ACTIVATION(Mish) -DECLARE_NO_PARAMETER_ACTIVATION(HardSigmoid) DECLARE_NO_PARAMETER_ACTIVATION(SoftRelu) #undef DEFINE_NO_PARAMETER_ACTIVATION @@ -100,6 +99,17 @@ class Prelu : public DirectMapOp { int axis_; }; +class HardSigmoid : public DirectMapOp { + public: + HardSigmoid(Graph* graph, float alpha, float beta); + std::shared_ptr Clone( + std::shared_ptr& graph) const override; + + protected: + float alpha_; + float beta_; +}; + class LeakyRelu : public DirectMapOp { public: LeakyRelu(Graph* graph, float alpha); diff --git a/src/tim/transform/ops/activation_layout_inference.h b/src/tim/transform/ops/activation_layout_inference.h index bf35f6d..929d004 100644 --- a/src/tim/transform/ops/activation_layout_inference.h +++ b/src/tim/transform/ops/activation_layout_inference.h @@ -46,7 +46,7 @@ class ActivationLayoutInfer : public OpLayoutInfer { assert(op_->impl()->InputsTensor().size() == 1); auto i_src = op_->impl()->InputsTensor()[0]; auto input_pv = context_->GetPermuteVector(i_src); - auto activation = context_->infer_graph_->CreateOperation(); + auto activation = op_->Clone(context_->infer_graph_); auto out_infer = CreateOutputsTensor(input_pv); (*activation) .BindInput(context_->GetMapedTensor(i_src)) @@ -56,30 +56,6 @@ class ActivationLayoutInfer : public OpLayoutInfer { } }; -class LeakyReluLayoutInfer : public OpLayoutInfer { - public: - LeakyReluLayoutInfer( - const std::shared_ptr op, - std::shared_ptr& context) - : OpLayoutInfer(op, context) {} - - void OnInputs( - std::vector>& next_tensors) override { - assert(op_->impl()->InputsTensor().size() == 1); - auto i_src = op_->impl()->InputsTensor()[0]; - auto input_pv = context_->GetPermuteVector(i_src); - auto leaky_relu = - context_->infer_graph_->CreateOperation( - op_->impl()->node()->nn_param.activation.leaky_ratio); - auto out_infer = CreateOutputsTensor(input_pv); - (*leaky_relu) - .BindInput(context_->GetMapedTensor(i_src)) - .BindOutput(out_infer[0]); - context_->SetPermuteVector(op_->impl()->OutputsTensor()[0], input_pv); - next_tensors.push_back(op_->impl()->OutputsTensor()[0]); - } -}; - class PReluLayoutInfer : public OpLayoutInfer { public: PReluLayoutInfer( @@ -107,6 +83,7 @@ class PReluLayoutInfer : public OpLayoutInfer { using ReluLayoutInfer = ActivationLayoutInfer; using Relu1LayoutInfer = ActivationLayoutInfer; using Relu6LayoutInfer = ActivationLayoutInfer; +using LeakyReluLayoutInfer = ActivationLayoutInfer; using EluLayoutInfer = ActivationLayoutInfer; using SigmoidLayoutInfer = ActivationLayoutInfer; using MishLayoutInfer = ActivationLayoutInfer; diff --git a/src/tim/vx/ops/activations.cc b/src/tim/vx/ops/activations.cc index 11e7243..3aca7d0 100644 --- a/src/tim/vx/ops/activations.cc +++ b/src/tim/vx/ops/activations.cc @@ -43,7 +43,6 @@ DEFINE_NO_PARAMETER_ACTIVATION(Relu6, VSI_NN_OP_RELU6) DEFINE_NO_PARAMETER_ACTIVATION(Elu, VSI_NN_OP_ELU) DEFINE_NO_PARAMETER_ACTIVATION(Sigmoid, VSI_NN_OP_SIGMOID) DEFINE_NO_PARAMETER_ACTIVATION(Mish, VSI_NN_OP_MISH) -DEFINE_NO_PARAMETER_ACTIVATION(HardSigmoid, VSI_NN_OP_HARD_SIGMOID) DEFINE_NO_PARAMETER_ACTIVATION(SoftRelu, VSI_NN_OP_SOFTRELU) @@ -78,6 +77,16 @@ std::shared_ptr Prelu::Clone(std::shared_ptr& graph) const { return graph->CreateOperation(this->axis_); } +HardSigmoid::HardSigmoid(Graph* graph, float alpha, float beta) + : DirectMapOp(graph, VSI_NN_OP_HARD_SIGMOID), alpha_(alpha), beta_(beta) { + this->impl()->node()->nn_param.hard_sigmoid.alpha = alpha_; + this->impl()->node()->nn_param.hard_sigmoid.beta = beta_; +} + +std::shared_ptr HardSigmoid::Clone(std::shared_ptr& graph) const { + return graph->CreateOperation(this->alpha_, this->beta_); +} + Tanh::Tanh(Graph* graph) : DirectMapOp(graph, VSI_NN_OP_TANH) { this->impl()->node()->nn_param.tanh.scale_a = 1.0; this->impl()->node()->nn_param.tanh.scale_b = 1.0; diff --git a/src/tim/vx/ops/activations_test.cc b/src/tim/vx/ops/activations_test.cc index fad39ae..62331e8 100644 --- a/src/tim/vx/ops/activations_test.cc +++ b/src/tim/vx/ops/activations_test.cc @@ -177,4 +177,54 @@ TEST(Gelu, shape_5_1_uint8_Quantized) { EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); EXPECT_TRUE(ArraysMatch(golden, output, (uint8_t)1)); -} \ No newline at end of file +} + +TEST(HardSigmoid, shape_5_1_uint8_Quantized) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType in_shape({20, 1}); + tim::vx::ShapeType out_shape({20, 1}); + + std::vector scalesInput = {0.00228914}; //scale + std::vector zeroPointsInput = {128}; //zero point + + std::vector scalesOutput = {0.005}; + std::vector zeroPointsOutput = {128}; + + tim::vx::Quantization quantInput(tim::vx::QuantType::ASYMMETRIC, 1, + scalesInput, zeroPointsInput); + tim::vx::Quantization quantOutput(tim::vx::QuantType::ASYMMETRIC, 1, + scalesOutput, zeroPointsOutput); + + tim::vx::TensorSpec input_spec(tim::vx::DataType::UINT8, in_shape, + tim::vx::TensorAttribute::INPUT, quantInput); + + tim::vx::TensorSpec output_spec(tim::vx::DataType::UINT8, out_shape, + tim::vx::TensorAttribute::OUTPUT, + quantOutput); + + auto input_tensor = graph->CreateTensor(input_spec); + auto output_tensor = graph->CreateTensor(output_spec); + + std::vector in_data = {65, 255, 140, 92, 142, + 122, 117, 167, 132, 117, + 44, 99, 109, 96, 216, + 222, 135, 126, 113, 100}; + std::vector golden_data = {222, 240, 229, 225, 229, + 227, 227, 232, 228, 227, + 220, 225, 226, 225, 236, + 237, 229, 228, 227, 225}; + + EXPECT_TRUE( + input_tensor->CopyDataToTensor(in_data.data(), in_data.size())); + auto op = graph->CreateOperation(0.2, 0.5); + (*op).BindInput(input_tensor).BindOutput(output_tensor); + + EXPECT_TRUE(graph->Compile()); + EXPECT_TRUE(graph->Run()); + std::vector output(golden_data.size()); + + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); + EXPECT_TRUE(ArraysMatch(golden_data, output, (uint8_t)1)); +}