| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_LOGISTIC_H_ |
| #define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_LOGISTIC_H_ |
|
|
| #include <cmath> |
|
|
| #include "edge-impulse-sdk/third_party/gemmlowp/fixedpoint/fixedpoint.h" |
| #include "edge-impulse-sdk/tensorflow/lite/kernels/internal/common.h" |
| #include "edge-impulse-sdk/tensorflow/lite/kernels/internal/cppmath.h" |
| #include "edge-impulse-sdk/tensorflow/lite/kernels/internal/quantization_util.h" |
| #include "edge-impulse-sdk/tensorflow/lite/kernels/internal/types.h" |
| #include "edge-impulse-sdk/tensorflow/lite/kernels/op_macros.h" |
|
|
| namespace tflite { |
| namespace reference_ops { |
|
|
| inline void Logistic(const RuntimeShape& input_shape, const float* input_data, |
| const RuntimeShape& output_shape, float* output_data) { |
| const float cutoff_upper = 16.619047164916992188f; |
| const float cutoff_lower = -9.f; |
|
|
| const int flat_size = MatchingFlatSize(input_shape, output_shape); |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| for (int i = 0; i < flat_size; i++) { |
| float val = input_data[i]; |
| float result; |
| if (val > cutoff_upper) { |
| result = 1.0f; |
| } else if (val < cutoff_lower) { |
| result = std::exp(val); |
| } else { |
| result = 1.f / (1.f + std::exp(-val)); |
| } |
| output_data[i] = result; |
| } |
| } |
|
|
| |
| |
| inline void Logistic(const LogisticParams&, const RuntimeShape& input_shape, |
| const float* input_data, const RuntimeShape& output_shape, |
| float* output_data) { |
| |
| Logistic(input_shape, input_data, output_shape, output_data); |
| } |
|
|
| inline void Logistic(const LogisticParams& params, |
| const RuntimeShape& input_shape, const int16_t* input_data, |
| const RuntimeShape& output_shape, int16_t* output_data) { |
| const int flat_size = MatchingFlatSize(input_shape, output_shape); |
|
|
| for (int i = 0; i < flat_size; i++) { |
| |
| |
| |
| using F0 = gemmlowp::FixedPoint<std::int16_t, 0>; |
| |
| using F3 = gemmlowp::FixedPoint<std::int16_t, 3>; |
|
|
| const F3 input = F3::FromRaw(input_data[i]); |
| F0 output = gemmlowp::logistic(input); |
| output_data[i] = output.raw(); |
| } |
| } |
|
|
| |
| |
| |
|
|
| |
| |
| inline void Logistic(const RuntimeShape& input_shape, const int8_t* input_data, |
| float input_scale, int input_zero_point, |
| const RuntimeShape& output_shape, int8_t* output_data, |
| float output_scale, int output_zero_point) { |
| const float cutoff_upper = 16.619047164916992188f; |
| const float cutoff_lower = -9.f; |
|
|
| const int flat_size = MatchingFlatSize(input_shape, output_shape); |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| for (int i = 0; i < flat_size; i++) { |
| |
| float val = |
| static_cast<float>((input_data[i] - input_zero_point) * input_scale); |
| float result; |
| if (val > cutoff_upper) { |
| result = 1.0f; |
| } else if (val < cutoff_lower) { |
| result = std::exp(val); |
| } else { |
| result = 1.f / (1.f + std::exp(-val)); |
| } |
| |
| int8_t output = |
| static_cast<int8_t>(result / output_scale + output_zero_point); |
| output_data[i] = output; |
| } |
| } |
|
|
| } |
| } |
|
|
| #endif |
|
|