【问题标题】:Tensorflow lite model output always gives same output no matter the input无论输入如何,Tensorflow lite 模型输出总是给出相同的输出
【发布时间】:2020-07-29 21:43:21
【问题描述】:

我的目标是运行我在 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 = &micro_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++ 应用程序中正确使用模型?

【问题讨论】:

    标签: c++ tensorflow keras model esp32


    【解决方案1】:

    您能否参考此处的“测试模型”部分 - 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 Micro Model(C 源文件)来找到问题

    您还需要验证传递给模型的输入是否具有相同的类型和分布。例如:如果您的 TFModel 是在 0-255 范围内的图像上训练的,那么您需要将其传递给 TFLite 和 TFLite Micro Model。相反,如果您使用预处理数据训练模型(在训练期间将 0-255 归一化为 0-1),那么您需要执行相同的操作并预处理 TFLite 和 TFLite Micro 模型的数据。

    【讨论】:

      【解决方案2】:

      我找到了问题和答案。

      这不是 C++ 代码,而是模型。最初,我用 64、20 和 8 的 3 个隐藏层制作了我的模型(我是 ML 新手,所以我只玩随机值),这给了我问题。

      为了解决这个问题,我只是将隐藏层更改为 32、16 和 8 并且 C++ 代码输出了正确的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-11
        • 2017-11-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        相关资源
        最近更新 更多