Hello Tensorflow Team,
i want to put acceleration and gyroscope sensordata into a full int8 quantified neural network. All this should run on an ESP32 microcontroller and i use the Arduino IDE 2.0.2. The data the sensor gives me is a matrix with the shape (6,128). I normalize and then quantify the matrix like it is shown in the hello world example. But now i have the problem that i don’t know on how to put my matrix into the network to make predictions. As i try to do this it throws an error. I will link my code and error below. It is still work in progress.
Thanks in advance.
The Code:
// Tensorflow imports
#include <TensorFlowLite_ESP32.h>
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/system_setup.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "ESP32_Model.h"
// MPU-6050 imports
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
// Create Memory arena for calculations
constexpr int kTensorArenaSize = 8192;
uint8_t tensor_arena[kTensorArenaSize];
}
void setup(){
// Set up the MPU-6050 --------------------------------------------
Serial.begin(9600);
while (!Serial){
delay(10);
}
if (!mpu.begin()) {
while (1) {
delay(10);
}
}
mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
mpu.setGyroRange(MPU6050_RANGE_250_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
// Set up Tensorflow ----------------------------------------------
static tflite::MicroErrorReporter micro_error_reporter;
error_reporter = µ_error_reporter;
// Map the model into a usable data structure. This doesn't involve any
// copying or parsing, it's a very lightweight operation.
model = tflite::GetModel(ESP32_Model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
TF_LITE_REPORT_ERROR(error_reporter,
"Model provided is schema version %d not equal "
"to supported version %d.",
model->version(), TFLITE_SCHEMA_VERSION);
return;
}
// This pulls in all the operation implementations we need.
// NOLINTNEXTLINE(runtime-global-variables)
static tflite::AllOpsResolver resolver;
// Build an interpreter to run the model with.
static tflite::MicroInterpreter static_interpreter(
model, resolver, tensor_arena, kTensorArenaSize, error_reporter);
interpreter = &static_interpreter;
// Allocate memory from the tensor_arena for the model's tensors.
TfLiteStatus allocate_status = interpreter->AllocateTensors();
if (allocate_status != kTfLiteOk) {
TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed");
return;
}
// Obtain pointers to the model's input and output tensors.
input = interpreter->input(2);
output = interpreter->output(2);
}
float Accx = 0.0;
float Accy = 0.0;
float Accz = 0.0;
float Gyrx = 0.0;
float Gyry = 0.0;
float Gyrz = 0.0;
float Temp = 0.0;
sensors_event_t Acc, Gyr, Temps;
float Input_Matrix_float[6][128];
float Output_Matrix_float[6][128];
float Input_Matrix_norm[6][128];
int8_t Input_Matrix_quant[6][128];
int8_t Output_Matrix_quant[6][128];
int Index = 0;
float Max = 0.0;
float Min = 0.0;
int counter = 0;
int Pos_Min = 0;
int Pos_Max = 0;
int8_t Storage = 0;
float Abs_Sum = 0.0;
float MAE = 0.0;
void loop(){
mpu.getEvent(&Acc,&Gyr,&Temps);
Input_Matrix_float[0][Index] = Acc.acceleration.x;
Input_Matrix_float[1][Index] = Acc.acceleration.y;
Input_Matrix_float[2][Index] = Acc.acceleration.z;
Input_Matrix_float[3][Index] = Gyr.acceleration.x;
Input_Matrix_float[4][Index] = Gyr.acceleration.y;
Input_Matrix_float[5][Index] = Gyr.acceleration.z;
Index += 1;
if (Index==128){
Serial.print("\n");
Serial.print("\n");
Serial.print("\n");
Serial.print("Input Matrix float\n");
counter = 0;
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Serial.print(Input_Matrix_float[k][i]);
Serial.print(" ");
}
Serial.print(counter);
Serial.print("\n");
counter += 1;
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
if (Max < Input_Matrix_float[k][i]){
Max = Input_Matrix_float[k][i];
Pos_Max = i;
}
if (Min > Input_Matrix_float[k][i]){
Min = Input_Matrix_float[k][i];
Pos_Min = i;
}
}
}
Serial.print("Min Wert\n");
Serial.print(Min);
Serial.print(" ");
Serial.print(Pos_Min);
Serial.print("\nMax Wert\n");
Serial.print(Max);
Serial.print(" ");
Serial.print(Pos_Max);
Serial.print("\n");
counter = 0;
Serial.print("Input Matrix norm\n");
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Input_Matrix_norm[k][i] = (2*(Input_Matrix_float[k][i]-Min)/(Max-Min))-1;
Serial.print(Input_Matrix_norm[k][i]);
Serial.print(" ");
}
Serial.print(counter);
Serial.print("\n");
counter += 1;
}
counter = 0;
Serial.print("Input Matrix quant\n");
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Input_Matrix_quant[k][i] = int8_t(Input_Matrix_float[k][i] / input->params.scale + input->params.zero_point);
Serial.print(Input_Matrix_quant[k][i]);
Serial.print(" ");
}
Serial.print(counter);
Serial.print("\n");
counter += 1;
}
//?????
input->data.int8[0] = Input_Matrix_quant;
TfLiteStatus invoke_status = interpreter->Invoke();
if (invoke_status != kTfLiteOk) {
TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed on x: %f\n",
static_cast<double>(Input_Matrix_quant));
return;
counter = 0;
Serial.print("Output Matrix quant\n");
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Output_Matrix_quant[k][i] = output->data.int8[k][i];
Serial.print(Output_Matrix_quant[k][i]);
Serial.print(" ");
}
Serial.print(counter);
Serial.print("\n");
}
counter = 0;
Serial.print("Output Matrix float\n");
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Output_Matrix_float[k][i] = (Output_Matrix_quant[k][i]-params.zero_point)*output->params.scale;
Serial.print(Output_Matrix_float[k][i]);
Serial.print(" ");
}
Serial.print(counter);
Serial.print("\n");
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Abs_Sum += sqrt(sq(Output_Matrix_float[k][i]));
}
}
MAE = Abs_Sum/(6*128);
Serial.print("MAE ist: ");
Serial.print(MAE);
Serial.print("\n");
// Set all Arrays and Vars to 0
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Input_Matrix_float[k][i] = 0.0;
}
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Input_Matrix_norm[k][i] = 0.0;
}
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Input_Matrix_quant[k][i] = 0;
}
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Output_Matrix_quant[k][i] = 0;
}
}
for (int i=0; i<128; i++){
for (int k=0; k<6; k++){
Output_Matrix_float[k][i] = 0.0;
}
}
Min = 0.0;
Max = 0.0;
Pos_Min = 0;
Pos_Max = 0;
counter = 0;
Abs_Sum = 0.0;
MAE = 0.0;
Index = 0;
}
delay(4);
}
The Error:
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino: In function 'void loop()':
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:197:27: error: invalid conversion from 'int8_t (*)[128]' {aka 'signed char (*)[128]'} to 'int8_t' {aka 'signed char'} [-fpermissive]
input->data.int8[0] = Input_Matrix_quant;
^~~~~~~~~~~~~~~~~~
In file included from c:\Users\PaulR\Documents\Arduino\libraries\TensorFlowLite_ESP32\src/tensorflow/lite/micro/micro_mutable_op_resolver.h:22,
from c:\Users\PaulR\Documents\Arduino\libraries\TensorFlowLite_ESP32\src/tensorflow/lite/micro/all_ops_resolver.h:19,
from C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:3:
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:203:64: error: invalid static_cast from type 'int8_t [6][128]' {aka 'signed char [6][128]'} to type 'double'
static_cast<double>(Input_Matrix_quant));
^
c:\Users\PaulR\Documents\Arduino\libraries\TensorFlowLite_ESP32\src/tensorflow/lite/core/api/error_reporter.h:53:59: note: in definition of macro 'TF_LITE_REPORT_ERROR'
static_cast<tflite::ErrorReporter*>(reporter)->Report(__VA_ARGS__); \
^~~~~~~~~~~
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:210:59: error: invalid types 'int8_t {aka signed char}[int]' for array subscript
Output_Matrix_quant[k][i] = output->data.int8[k][i];
^
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:222:64: error: 'params' was not declared in this scope
Output_Matrix_float[k][i] = (Output_Matrix_quant[k][i]-params.zero_point)*output->params.scale;
^~~~~~
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:286:1: error: expected '}' at end of input
}
^
C:\Users\PaulR\Documents\Arduino\ESP32_Model_with_MPU6050\ESP32_Model_with_MPU6050.ino:112:12: note: to match this '{'
void loop(){
^
exit status 1
Compilation error: invalid conversion from 'int8_t (*)[128]' {aka 'signed char (*)[128]'} to 'int8_t' {aka 'signed char'} [-fpermissive]