提交 957ad169 编写于 作者: L liu zhengxi 提交者: GitHub

add leaky_relu op for x86, test=develop (#2819)

上级 f41a0c4a
......@@ -100,3 +100,4 @@ lite_cc_test(test_sequence_concat_compute_x86 SRCS sequence_concat_compute_test.
lite_cc_test(test_var_conv_2d_compute_x86 SRCS var_conv_2d_compute_test.cc DEPS var_conv_2d_compute_x86)
#lite_cc_test(test_attention_padding_mask_compute_x86 SRCS attention_padding_mask_compute_test.cc DEPS attention_padding_mask_compute_x86)
lite_cc_test(test_sequence_arithmetic_compute_x86 SRCS sequence_arithmetic_compute_test.cc DEPS sequence_arithmetic_compute_x86)
lite_cc_test(test_leaky_relu_compute_x86 SRCS leaky_relu_compute_test.cc DEPS activation_compute_x86)
......@@ -36,6 +36,17 @@ REGISTER_LITE_KERNEL(relu,
.BindOutput("Out", {LiteType::GetTensorTy(TARGET(kX86))})
.Finalize();
// float
REGISTER_LITE_KERNEL(leaky_relu,
kX86,
kFloat,
kNCHW,
paddle::lite::kernels::x86::LeakyReluCompute<float>,
def)
.BindInput("X", {LiteType::GetTensorTy(TARGET(kX86))})
.BindOutput("Out", {LiteType::GetTensorTy(TARGET(kX86))})
.Finalize();
// float
REGISTER_LITE_KERNEL(tanh,
kX86,
......
......@@ -117,6 +117,40 @@ class ReluCompute : public KernelLite<TARGET(kX86), PRECISION(kFloat)> {
virtual ~ReluCompute() = default;
};
template <typename T>
struct LeakyReluFunctor {
float alpha;
explicit LeakyReluFunctor(float alpha_) : alpha(alpha_) {}
template <typename Device, typename X, typename Out>
void operator()(Device d, X x, Out out) const {
out.device(d) = x.cwiseMax(static_cast<T>(alpha) * x);
}
};
template <typename T>
class LeakyReluCompute : public KernelLite<TARGET(kX86), PRECISION(kFloat)> {
public:
using param_t = operators::ActivationParam;
void Run() override {
auto& param = *param_.get_mutable<operators::ActivationParam>();
param.Out->template mutable_data<T>();
auto X = param.X;
auto Out = param.Out;
auto place = lite::fluid::EigenDeviceType<TARGET(kX86)>();
CHECK(X);
CHECK(Out);
auto x = lite::fluid::EigenVector<T>::Flatten(*X);
auto out = lite::fluid::EigenVector<T>::Flatten(*Out);
LeakyReluFunctor<T> functor(param.Leaky_relu_alpha);
functor(place, x, out);
}
virtual ~LeakyReluCompute() = default;
};
// tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
template <typename T>
struct TanhFunctor : public BaseActivationFunctor<T> {
......
......@@ -155,7 +155,6 @@ TEST(layer_norm_x86, run_test) {
ref(&x, &Scale, &Bias, &out, &Mean, &Var, begin_norm_axis, epsilon);
for (int j = 0; j < out.dims().production(); ++j) {
EXPECT_NEAR(out_data[j], ref_data[j], 1e-5);
// LOG(INFO) << out_data[j];
}
LOG(INFO) << *mean_data;
LOG(INFO) << *var_data;
......
// Copyright (c) 2019 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 <gtest/gtest.h>
#include <iostream>
#include <vector>
#include "lite/core/op_registry.h"
#include "lite/kernels/x86/activation_compute.h"
namespace paddle {
namespace lite {
namespace kernels {
namespace x86 {
TEST(leaky_relu_x86, retrive_op) {
auto leaky_relu =
KernelRegistry::Global().Create<TARGET(kX86), PRECISION(kFloat)>(
"leaky_relu");
ASSERT_FALSE(leaky_relu.empty());
ASSERT_TRUE(leaky_relu.front());
}
TEST(leaky_relu_x86, init) {
LeakyReluCompute<float> leaky_relu;
ASSERT_EQ(leaky_relu.precision(), PRECISION(kFloat));
ASSERT_EQ(leaky_relu.target(), TARGET(kX86));
}
TEST(leaky_relu_x86, run_test) {
lite::Tensor x, out;
constexpr int batch_size = 1;
std::vector<int64_t> x_shape{batch_size, 3, 2, 2};
x.Resize(lite::DDim(x_shape));
std::vector<int64_t> out_shape{batch_size, 3, 2, 2};
out.Resize(lite::DDim(out_shape));
auto x_data = x.mutable_data<float>();
auto out_data = out.mutable_data<float>();
for (int64_t i = 0; i < x.dims().production(); i++) {
x_data[i] = static_cast<float>(i) / 12.0 - 0.5;
}
LeakyReluCompute<float> leaky_relu;
operators::ActivationParam param;
param.X = &x;
param.Out = &out;
param.Leaky_relu_alpha = 0.05;
leaky_relu.SetParam(param);
leaky_relu.Run();
std::vector<float> ref_data({-0.025,
-0.02083333,
-0.01666667,
-0.0125,
-0.00833333,
-0.00416667,
0.,
0.08333334,
0.16666667,
0.25,
0.33333334,
0.41666666});
for (int i = 0; i < out.dims().production(); i++) {
EXPECT_NEAR(out_data[i], ref_data[i], 1e-05);
}
}
} // namespace x86
} // namespace kernels
} // namespace lite
} // namespace paddle
USE_LITE_KERNEL(leaky_relu, kX86, kFloat, kNCHW, def);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册