google-coral / coralmicro

Source code for Coral Dev Board Micro
Apache License 2.0
106 stars 44 forks source link

Problems getting custom model to run on edge_tpu #104

Open Perugius opened 6 months ago

Perugius commented 6 months ago

Description

I am trying to get my simple model to run on the edge tpu. Graph of model image

Graph of model compiled for edge-tpu image

I have followed the edge-tpu runtime guide, but when I flash the script it doesn't work, there is no output similar to when the OP resolver doesn't correctly add all the ops. I also included the correct path to the edge-tpu model in the CMake file.

Is there a problem with my code, is it the model itself, or am I just encountering a bug?

#include <cstdio>
#include <chrono>
#include "libs/tensorflow/utils.h"
#include "examples/tflm_hello_world/hello_world_model.h"
#include "libs/base/led.h"
#include "libs/base/timer.h"
#include <climits>
#include <ctime>
#include <stdint.h>
#include "libs/tpu/edgetpu_manager.h"
#include "libs/tpu/edgetpu_op.h"
#include "third_party/freertos_kernel/include/FreeRTOS.h"
#include "third_party/freertos_kernel/include/task.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/all_ops_resolver.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/micro_error_reporter.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/micro_interpreter.h"
#include "libs/base/filesystem.h"
// Runs a tiny TFLM model on the M7 core, NOT on the Edge TPU, which simply
// outputs sine wave values over time in the serial console.
//
// For more information about this model, see:
// https://github.com/tensorflow/tflite-micro/tree/main/tensorflow/lite/micro/examples
//
// To build and flash from coralmicro root:
//    bash build.sh
//    python3 scripts/flashtool.py -e tflm_hello_world

const int test_data[] = { 
4,4,9,3,6,8,0,8,7,4,8,2,0,6,6,7,1,2,6,1,9,0,6,8,6,8,8,7,1,3,5,8,9,9,8,6,4,6,1,7,3,2,6,5,5,8,7,6,6,7,3,9,2,5,2,1,5,1,3,8,7,6,9,6,2,2,7,4,0,9,2,4,5,8,7,5,8,7,0,8,8,3,0,1,3,0,2,7,9,6,5,4,3,9,2,0,1,8,0,3,5,2,5,9,4,4,7,4,2,6,7,5,7,3,7,6,8,9,2,7,1,3,9,7,1,0,3,8,0,5,3,2,9,2,3,2,1,1,2,1,0,1,8,7,4,0,4,9,1,5,4,3,8,0,7,5,3,2,0,2,3,1,6,2,5,7,0,9,3,3,2,2,8,6,5,6,2,6,1,2,4,7,8,8,3,3,8,9,0,7,5,6,9,1,5,0,6,1,3,0,8,3,9,2,9,9,7,7,7,1,9,1,5,3,8,0,5,1,9,2,0,0,6,9,4,2,9,2,7,2,1,1,3,4,0,5,8,8,7,3,
};

// const float test_data[] = { 
// 0.22768896476796524,0.2047959025298774,0.21628123544932484,0.2037094521185783,0.2047959025298774,0.193388173211237,0.17049511097314915,0.18190284029178955,0.1590097780537017,0.1590097780537017,0.1590097780537017,0.16940866056185008,0.13619431941642093,0.09040819494024523,0.0,0.3295048890268508,0.5228930622380878,0.7723110352320348,0.6476020487350613,0.5114077293186404,0.39702002172900824,0.4199130839670961,0.3741269594909204,0.3741269594909204,0.35239795126493867,0.2952040974701226,0.28379636815148224,0.2494179729939469,0.2151171814372187,0.21628123544932484,0.2390966940866056,0.26198975632469346,0.28379636815148224,0.32841843861555176,0.3409902219462983,0.4210771379792022,0.5,0.5904081949402452,0.7047959025298773,0.8054477727766568,0.9313208132857365,1.0,0.8741269594909203,0.7379326400744994,0.7150395778364116,0.6578457240415956,0.3752910135030265,0.12470898649697346,0.0,0.011485332919447462,0.03321434114542915,0.06751513270215738,0.07900046562160484,0.06751513270215738,0.09149464535154431,0.06867918671426354,0.056107403383516996,0.056107403383516996,0.07900046562160484,0.10189352785969269,0.8333965844402277,0.8333965844402277,0.8473434535104364,0.8195445920303606,0.8333965844402277,0.8329222011385199,0.8333965844402277,0.8329222011385199,0.8333965844402277,0.8329222011385199,0.8467741935483871,0.8467741935483871,0.8752371916508539,0.8752371916508539,0.9443074003795067,0.9860531309297913,1.0,0.7637571157495257,0.27751423149905124,0.04127134724857685,0.0,0.19392789373814043,0.22229601518026565,0.15265654648956356,0.12485768500948767,0.11091081593927894,0.11091081593927894,0.09743833017077799,0.08358633776091082,0.11091081593927894,0.13870967741935483,0.1666034155597723,0.18055028462998102,0.1944022770398482,0.18055028462998102,0.22229601518026565,0.3057874762808349,0.4306451612903226,0.47239089184060723,0.444022770398482,0.6663187855787476,0.8195445920303606,0.9164136622390892,0.9860531309297913,0.9994307400379506,0.9722011385199241,0.930360531309298,0.902561669829222,0.8891840607210626,0.9031309297912713,0.902561669829222,0.8752371916508539,0.8886148007590133,0.8746679316888045,0.8886148007590133,0.8886148007590133,0.8746679316888045,0.8607210626185958,0.8473434535104364,0.8467741935483871,0.7136757350250091,0.695498353055996,0.7157496645114066,0.7067219714529706,0.9636452360619739,0.9818226180309869,0.9839575454434549,0.9657801634744418,0.9546175430035378,0.7954129559594973,0.7339270464804196,0.7409418079785287,0.7045870440405027,0.679455898499451,0.7954129559594973,0.34982310601439554,0.18854458948395755,0.24094180797852874,0.14316213248749543,0.0,0.15225082347200194,0.2318531169940222,0.22276442600951568,0.4365011589605953,0.5453824569964622,0.5272050750274491,0.5544711479809686,0.4637062339880444,0.4476027815054288,0.4385140905209223,0.3931316335244602,0.4022203245089667,0.42039770647797975,0.4294863974624863,0.4385140905209223,0.4476027815054288,0.5705136025375137,0.6543247529583994,0.6976332804684641,0.4476027815054288,0.7681468830059778,0.8861778699524216,0.9909113090154935,0.9364401610345249,0.8589727949249726,0.9022203245089667,1.0,0.9113090154934732,0.7863242649749909,0.6976332804684641,0.6613395144565085,0.6885445894839576,0.6613395144565085,0.7136757350250091,0.8044406490179334,0.7772355739904844,0.6976332804684641,0.679455898499451,0.6976332804684641,0.6976332804684641,0.03571894784935709,0.0494093074864565,0.05774753606161478,0.05774753606161478,0.12463285686312904,0.1337543241302787,0.1497454474251028,0.1406076626852033,0.13146987794530382,0.08057568043861367,0.07600678806866393,0.06608576463677306,0.015175249657333072,0.0,0.10488871483584622,0.17175771816461066,0.29492200248025585,0.40813262841851056,0.4841557339599243,0.5373180601788395,0.5570458847333725,0.5844755564258207,0.5927648325827296,0.5904803863977547,0.5707525618432218,0.5973337249526793,0.5904803863977547,0.5098883884863912,0.5107368970693819,0.5410384439657986,0.5844755564258207,0.6527804973565694,0.6962339272893414,0.7333888127406827,0.750815873637491,0.780546308987664,0.8002578160694471,0.8337086352065792,0.7728118269042491,0.7045232034462502,0.8314078715488545,0.9303407088310163,1.0,0.943182559885125,0.7393773252398669,0.5510410547614385,0.3069806148423732,0.29182168265778996,0.28349977155538153,0.274361986815482,0.20063964493179295,0.16720514326741073,0.14436068141766203,0.15431433979505255,0.19607075256184323,0.1983551987468181,0.16035180471248614,0.14892957378761176,0.14207623523268717,0.14517655505515306,
// };

namespace coralmicro {
namespace{

uint64_t startTime;
uint64_t endTime;
uint64_t inferenceTime;

int inference_count = 0;
const int kInferencesPerCycle = 1000;

// An area of memory to use for input, output, and intermediate arrays.
constexpr int kTensorArenaSize = 8 * 1024 * 1024;
STATIC_TENSOR_ARENA_IN_SDRAM(tensor_arena, kTensorArenaSize);

[[noreturn]] void Main() {

  coralmicro::TimerInit();
  LedSet(Led::kStatus, true);

  //-----------------------------TURN ON EDGETPU---------------------------
  auto tpu_context = EdgeTpuManager::GetSingleton()->OpenDevice();
  if (!tpu_context) {
    printf("ERROR: Failed to get EdgeTpu context\r\n");
  }
  //-----------------------------END TURN ON EDGETPU---------------------------

  //---------------------------------LOAD MODEL-----------------------------
  constexpr char kModelPath[] = "/models/model_V4_QUANTIZED_edgetpu.tflite";

  std::vector<uint8_t> model;
  if (!LfsReadFile(kModelPath, &model)) {
    printf("ERROR: Failed to load %s\r\n", kModelPath);
    vTaskSuspend(nullptr);
  }
  //---------------------------END LOAD MODEL--------------------------------

  //---------------------------OP RESOLVER---------------------------------
  tflite::MicroErrorReporter error_reporter;
  tflite::MicroMutableOpResolver<10> resolver;
  resolver.AddQuantize();
  resolver.AddDequantize();
  resolver.AddDepthwiseConv2D();
  resolver.AddConv2D();
  resolver.AddExpandDims();
  resolver.AddReshape();
  resolver.AddMean();
  resolver.AddSoftmax();
  resolver.AddFullyConnected();
  resolver.AddLogistic();
  resolver.AddCustom(kCustomOp, RegisterCustomOp());
  //-------------------------END OP RESOLVER--------------------------------

  //-------------------------INTERPRETER INIT------------------------------

  tflite::MicroInterpreter interpreter(tflite::GetModel(model.data()),
                                     resolver, tensor_arena,
                                     kTensorArenaSize, &error_reporter);

  if (interpreter.AllocateTensors() != kTfLiteOk) {
    printf("ERROR: AllocateTensors() failed\r\n");
    vTaskSuspend(nullptr);
  }

  auto* input_tensor = interpreter.input_tensor(0);
  auto* output_tensor = interpreter.output_tensor(0);
  //----------------------END INTERPRETER INIT-----------------------------

  //------------------------START INFERENCE LOOP---------------------------
  while (true){

    vTaskDelay(pdMS_TO_TICKS(1000));
    //std::memcpy(tflite::GetTensorData<uint8_t>(input_tensor), test_data, sizeof(test_data));
    for (int i = 0; i < 240; i++) {
      input_tensor->data.uint8[i] = test_data[i];
      printf("\r\n progress: %d", i);
      //printf("\r\n %d", input_tensor->data.uint8[i]);
    }

    //-------------------------------INVOKE INTERPRETER-------------------------------
    startTime = coralmicro::TimerMicros();
    if (interpreter.Invoke() != kTfLiteOk) {
      printf("ERROR: Invoke() failed\r\n");
    }
    endTime = coralmicro::TimerMicros();
    inferenceTime = endTime-startTime;
    printf("inference time: %u \r\n ", (unsigned int)(inferenceTime));

    //-------------------------------END INVOKE INTERPRETER-------------------------------

    printf("inference time: %u \r\n ", (unsigned int)(inferenceTime));
    vTaskDelay(pdMS_TO_TICKS(10000));
  }
  //---------------------------END INFERENCE LOOP-------------------------------------
}
} //namespace 
} //namespace coralmicro

extern "C" void app_main(void* param) {
  (void)param;
  coralmicro::Main();
}
Click to expand! ### Issue Type Support ### Operating System Linux, Ubuntu ### Coral Device Dev Board Micro ### Other Devices _No response_ ### Programming Language C++ ### Relevant Log Output _No response_
Perugius commented 6 months ago

I suspect now that the problem is the input shape of the model, since I trained it on (4, 60), but the input array I am using is flat, which normally wouldn't be a problem, but it might cause problems on the edge-tpu. So I will try again with a new model trained with a flat input array.