无论输入如何,Tensorflow lite 模型输出总是给出相同的输出
Tensorflow lite model output always gives same output no matter the input
我的目标是 运行 我在 ESP32 微控制器中制作的 Keras 模型。我的库都正常工作。
我使用 google Collab 创建了一个 Keras 模型,当我在 google Collab 中给它随机测试数据时,它看起来工作正常。该模型有两个输入特征和 4 个不同的输出。(一个多输出回归模型)
但是,当我将模型导出并加载到我的 ESP32 中的 C++ 应用程序中时,输入是什么并不重要,它总是预测相同的输出。
我以这段代码为基础,以便加载和 运行 C++ 中的模型:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/magic_wand/main_functions.cc
这是我的代码版本
namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
int inference_count = 0;
// Create an area of memory to use for input, output, and intermediate arrays.
// Finding the minimum value for your model may require some trial and error.
constexpr int kTensorArenaSize = 2 * 2048;
uint8_t tensor_arena[kTensorArenaSize];
} // namespace
static void setup(){
static tflite::MicroErrorReporter micro_error_reporter;
error_reporter = µ_error_reporter;
model = tflite::GetModel(venti_model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
error_reporter->Report(
"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::ops::micro::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) {
error_reporter->Report("AllocateTensors() failed");
return;
}
// Obtain pointers to the model's input and output tensors.
input = interpreter->input(0);
ESP_LOGI("TENSOR SETUP", "input size = %d", input->dims->size);
ESP_LOGI("TENSOR SETUP", "input size in bytes = %d", input->bytes);
ESP_LOGI("TENSOR SETUP", "Is input float32? = %s", (input->type == kTfLiteFloat32) ? "true" : "false");
ESP_LOGI("TENSOR SETUP", "Input data dimentions = %d",input->dims->data[1]);
output = interpreter->output(0);
ESP_LOGI("TENSOR SETUP", "output size = %d", output->dims->size);
ESP_LOGI("TENSOR SETUP", "output size in bytes = %d", output->bytes);
ESP_LOGI("TENSOR SETUP", "Is input float32? = %s", (output->type == kTfLiteFloat32) ? "true" : "false");
ESP_LOGI("TENSOR SETUP", "Output data dimentions = %d",output->dims->data[1]);
}
static bool setupDone = true;
static void the_ai_algorithm_task(){
/* First time task is init setup the ai model */
if(setupDone == false){
setup();
setupDone = true;
}
/* Load the input data i.e deltaT1 and deltaT2 */
//int i = 0;
input->data.f[0] = 2.0; /* Different values dont change the output */
input->data.f[1] = 3.2;
// Run inference, and report any error
TfLiteStatus invoke_status = interpreter->Invoke();
if (invoke_status != kTfLiteOk) {
error_reporter->Report("Invoke failed");
// return;
}
/* Retrieve outputs Fan , AC , Vent 1 , Vent 2 */
double fan = output->data.f[0];
double ac = output->data.f[1];
double vent1 = output->data.f[2];
double vent2 = output->data.f[3];
ESP_LOGI("TENSOR SETUP", "fan = %lf", fan);
ESP_LOGI("TENSOR SETUP", "ac = %lf", ac);
ESP_LOGI("TENSOR SETUP", "vent1 = %lf", vent1);
ESP_LOGI("TENSOR SETUP", "vent2 = %lf", vent2);
}
模型似乎加载正常,因为尺寸和大小正确。但是输出总是相同的4个值
fan = 0.0087
ac = 0.54
vent1 = 0.73
vent2 = 0.32
知道会出什么问题吗?是关于我的模型还是我没有在我的 C++ 应用程序中正确使用模型?
您能否参考此处的“测试模型”部分 - https://colab.research.google.com/github/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/hello_world/train/train_hello_world_model.ipynb#scrollTo=f86dWOyZKmN9 并验证 TFLite 模型是否产生了正确的结果?
您可以通过测试 1) TFModel(您已经完成)2) TFLite 模型和 3) TFLite 微型模型(C 源文件)找到问题
您还需要验证传递给模型的输入是否具有相同的类型和分布。例如:如果您的 TFModel 是在 0-255 范围内的图像上训练的,那么您需要将其传递给 TFLite 和 TFLite 微模型。相反,如果您使用预处理数据训练模型(训练期间 0-255 归一化为 0-1),那么您需要执行相同的操作并对 TFLite 和 TFLite Micro 模型的数据进行预处理。
我找到了问题和答案。
这不是 C++ 代码,而是模型。最初,我用 64、20 和 8 的 3 个隐藏层制作我的模型(我是 ML 的新手,所以我只玩随机值)并且它给了我问题。
为了解决这个问题,我只是将隐藏层更改为 32、16 和 8,C++ 代码输出了正确的值。
我的目标是 运行 我在 ESP32 微控制器中制作的 Keras 模型。我的库都正常工作。
我使用 google Collab 创建了一个 Keras 模型,当我在 google Collab 中给它随机测试数据时,它看起来工作正常。该模型有两个输入特征和 4 个不同的输出。(一个多输出回归模型)
但是,当我将模型导出并加载到我的 ESP32 中的 C++ 应用程序中时,输入是什么并不重要,它总是预测相同的输出。
我以这段代码为基础,以便加载和 运行 C++ 中的模型:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/magic_wand/main_functions.cc
这是我的代码版本
namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
int inference_count = 0;
// Create an area of memory to use for input, output, and intermediate arrays.
// Finding the minimum value for your model may require some trial and error.
constexpr int kTensorArenaSize = 2 * 2048;
uint8_t tensor_arena[kTensorArenaSize];
} // namespace
static void setup(){
static tflite::MicroErrorReporter micro_error_reporter;
error_reporter = µ_error_reporter;
model = tflite::GetModel(venti_model);
if (model->version() != TFLITE_SCHEMA_VERSION) {
error_reporter->Report(
"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::ops::micro::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) {
error_reporter->Report("AllocateTensors() failed");
return;
}
// Obtain pointers to the model's input and output tensors.
input = interpreter->input(0);
ESP_LOGI("TENSOR SETUP", "input size = %d", input->dims->size);
ESP_LOGI("TENSOR SETUP", "input size in bytes = %d", input->bytes);
ESP_LOGI("TENSOR SETUP", "Is input float32? = %s", (input->type == kTfLiteFloat32) ? "true" : "false");
ESP_LOGI("TENSOR SETUP", "Input data dimentions = %d",input->dims->data[1]);
output = interpreter->output(0);
ESP_LOGI("TENSOR SETUP", "output size = %d", output->dims->size);
ESP_LOGI("TENSOR SETUP", "output size in bytes = %d", output->bytes);
ESP_LOGI("TENSOR SETUP", "Is input float32? = %s", (output->type == kTfLiteFloat32) ? "true" : "false");
ESP_LOGI("TENSOR SETUP", "Output data dimentions = %d",output->dims->data[1]);
}
static bool setupDone = true;
static void the_ai_algorithm_task(){
/* First time task is init setup the ai model */
if(setupDone == false){
setup();
setupDone = true;
}
/* Load the input data i.e deltaT1 and deltaT2 */
//int i = 0;
input->data.f[0] = 2.0; /* Different values dont change the output */
input->data.f[1] = 3.2;
// Run inference, and report any error
TfLiteStatus invoke_status = interpreter->Invoke();
if (invoke_status != kTfLiteOk) {
error_reporter->Report("Invoke failed");
// return;
}
/* Retrieve outputs Fan , AC , Vent 1 , Vent 2 */
double fan = output->data.f[0];
double ac = output->data.f[1];
double vent1 = output->data.f[2];
double vent2 = output->data.f[3];
ESP_LOGI("TENSOR SETUP", "fan = %lf", fan);
ESP_LOGI("TENSOR SETUP", "ac = %lf", ac);
ESP_LOGI("TENSOR SETUP", "vent1 = %lf", vent1);
ESP_LOGI("TENSOR SETUP", "vent2 = %lf", vent2);
}
模型似乎加载正常,因为尺寸和大小正确。但是输出总是相同的4个值
fan = 0.0087
ac = 0.54
vent1 = 0.73
vent2 = 0.32
知道会出什么问题吗?是关于我的模型还是我没有在我的 C++ 应用程序中正确使用模型?
您能否参考此处的“测试模型”部分 - https://colab.research.google.com/github/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/hello_world/train/train_hello_world_model.ipynb#scrollTo=f86dWOyZKmN9 并验证 TFLite 模型是否产生了正确的结果?
您可以通过测试 1) TFModel(您已经完成)2) TFLite 模型和 3) TFLite 微型模型(C 源文件)找到问题
您还需要验证传递给模型的输入是否具有相同的类型和分布。例如:如果您的 TFModel 是在 0-255 范围内的图像上训练的,那么您需要将其传递给 TFLite 和 TFLite 微模型。相反,如果您使用预处理数据训练模型(训练期间 0-255 归一化为 0-1),那么您需要执行相同的操作并对 TFLite 和 TFLite Micro 模型的数据进行预处理。
我找到了问题和答案。
这不是 C++ 代码,而是模型。最初,我用 64、20 和 8 的 3 个隐藏层制作我的模型(我是 ML 的新手,所以我只玩随机值)并且它给了我问题。
为了解决这个问题,我只是将隐藏层更改为 32、16 和 8,C++ 代码输出了正确的值。