Daniel Konegen / MNIST_example

Dependencies:   mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fully_connected.h Source File

fully_connected.h

00001 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
00002 
00003 Licensed under the Apache License, Version 2.0 (the "License");
00004 you may not use this file except in compliance with the License.
00005 You may obtain a copy of the License at
00006 
00007     http://www.apache.org/licenses/LICENSE-2.0
00008 
00009 Unless required by applicable law or agreed to in writing, software
00010 distributed under the License is distributed on an "AS IS" BASIS,
00011 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 See the License for the specific language governing permissions and
00013 limitations under the License.
00014 ==============================================================================*/
00015 #ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_
00016 #define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_
00017 
00018 #include "tensorflow/lite/kernels/internal/common.h"
00019 
00020 namespace tflite {
00021 namespace reference_integer_ops {
00022 
00023 inline void FullyConnected(
00024     const FullyConnectedParams& params, const RuntimeShape& input_shape,
00025     const int8_t* input_data, const RuntimeShape& filter_shape,
00026     const int8_t* filter_data, const RuntimeShape& bias_shape,
00027     const int32* bias_data, const RuntimeShape& output_shape,
00028     int8_t* output_data) {
00029   const int32 input_offset = params.input_offset;
00030   const int32 filter_offset = params.weights_offset;
00031   const int32 output_offset = params.output_offset;
00032   const int32 output_multiplier = params.output_multiplier;
00033   const int output_shift = params.output_shift;
00034   const int32 output_activation_min = params.quantized_activation_min;
00035   const int32 output_activation_max = params.quantized_activation_max;
00036   TFLITE_DCHECK_GE(filter_shape.DimensionsCount(), 2);
00037   TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 2);
00038 
00039   TFLITE_DCHECK_LE(output_activation_min, output_activation_max);
00040   const int filter_dim_count = filter_shape.DimensionsCount();
00041   const int batches = output_shape.Dims(0);
00042   const int output_depth = output_shape.Dims(1);
00043   TFLITE_DCHECK_LE(output_depth, filter_shape.Dims(filter_dim_count - 2));
00044   const int accum_depth = filter_shape.Dims(filter_dim_count - 1);
00045   for (int b = 0; b < batches; ++b) {
00046     for (int out_c = 0; out_c < output_depth; ++out_c) {
00047       int32 acc = 0;
00048       for (int d = 0; d < accum_depth; ++d) {
00049         int32 input_val = input_data[b * accum_depth + d];
00050         int32 filter_val = filter_data[out_c * accum_depth + d];
00051         acc += (filter_val + filter_offset) * (input_val + input_offset);
00052       }
00053       if (bias_data) {
00054         acc += bias_data[out_c];
00055       }
00056       acc = MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift);
00057       acc += output_offset;
00058       acc = std::max(acc, output_activation_min);
00059       acc = std::min(acc, output_activation_max);
00060       output_data[out_c + output_depth * b] = static_cast<int8_t>(acc);
00061     }
00062   }
00063 }
00064 
00065 }  // namespace reference_integer_ops
00066 }  // namespace tflite
00067 
00068 #endif  // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_