본문 바로가기
공부/ML&DL

[머신러닝 공부] Tiny ML -18 / 제스처인식 어플리케이션 -2

by 로디네로 2022. 4. 16.
반응형

 

Chapter18. 제스처인식 어플리케이션

 

"

자이로센서를 이용해 간단한 제스처를 인식하는 어플리케이션을 만들어보자

"

목차 :

  • 개요 -> 이전장
  • 만들고자 하는 시스템 -> 이전장
  • 기본흐름 코드 -> 이전장
  • 제스처 감지 
  • MCU에 배포 -> 다음장
  • 마치며 -> 다음장

 

이전장링크

 

[머신러닝 공부] Tiny ML -17 / 제스처인식 어플리케이션 -1

Chapter17. 제스처인식 어플리케이션 " 자이로센서를 이용해 간단한 제스처를 인식하는 어플리케이션을 만들어보자 " 목차 : 개요 만들고자 하는 시스템 기본흐름 코드 제스처 감지 -> 다음장 MCU에

dbstndi6316.tistory.com


참고 repo

 

GitHub - tensorflow/tensorflow: An Open Source Machine Learning Framework for Everyone

An Open Source Machine Learning Framework for Everyone - GitHub - tensorflow/tensorflow: An Open Source Machine Learning Framework for Everyone

github.com

 

 


 

제스처 감지

 

▶main_functions.cc

 

▽input_length 변수는 모델의 입력 텐서 길이를 저장

▽should_clear_buffer 변수는 다음 실행될 때 가속도계 핸들러의 버퍼 삭제 여부를 나타내는 플래그

// 전역변수 선언
namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* model_input = nullptr;
int input_length;

// 메모리 영역 설정 (임의)
constexpr int kTensorArenaSize = 60 * 1024;
uint8_t tensor_arena[kTensorArenaSize];

// 버퍼를 지우고 다음 데이터를 가져올지 결정
bool should_clear_buffer = false;
}  // namespace

 

▽setup() : 추론 실행 준비

▽로깅 설정

void setup() {
  static tflite::MicroErrorReporter micro_error_reporter;  // NOLINT
  error_reporter = &micro_error_reporter;

 

▽모델을 데이터 구조에 매핑하는 작업

  model = tflite::GetModel(g_magic_wand_model_data);
  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;
  }

 

▽필요한 Op 구현을 가져온다.

   ▽max pool, conv2d, softmax 등이 있다.

 static tflite::MicroMutableOpResolver micro_mutable_op_resolver;  // NOLINT
  micro_mutable_op_resolver.AddBuiltin(
      tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
      tflite::ops::micro::Register_DEPTHWISE_CONV_2D());
  micro_mutable_op_resolver.AddBuiltin(
      tflite::BuiltinOperator_MAX_POOL_2D,
      tflite::ops::micro::Register_MAX_POOL_2D());
  micro_mutable_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
                                       tflite::ops::micro::Register_CONV_2D());
  micro_mutable_op_resolver.AddBuiltin(
      tflite::BuiltinOperator_FULLY_CONNECTED,
      tflite::ops::micro::Register_FULLY_CONNECTED());
  micro_mutable_op_resolver.AddBuiltin(tflite::BuiltinOperator_SOFTMAX,
                                       tflite::ops::micro::Register_SOFTMAX());

 

▽모델 실행을 위해 인터프리터를 빌드한다.

▽텐서에 메모리를 할당한다.

  static tflite::MicroInterpreter static_interpreter(
      model, micro_mutable_op_resolver, tensor_arena, kTensorArenaSize,
      error_reporter);
  interpreter = &static_interpreter;

  interpreter->AllocateTensors();

 

▽입력 텐서에 대한 포인터를 획득한다.

  model_input = interpreter->input(0);
  if ((model_input->dims->size != 4) || (model_input->dims->data[0] != 1) ||
      (model_input->dims->data[1] != 128) ||
      (model_input->dims->data[2] != kChannelNumber) ||
      (model_input->type != kTfLiteFloat32)) {
    error_reporter->Report("Bad input tensor parameters in model");
    return;
  }
    input_length = model_input->bytes / sizeof(float);

  TfLiteStatus setup_status = SetupAccelerometer(error_reporter);
  if (setup_status != kTfLiteOk) {
    error_reporter->Report("Set up failed\n");
  }
}

 

▽loop()함수

▽새 데이터를 읽는데 실패한다면 ReadAcclerometer는 이상값을 반환 후 loop()를 빠져나와 재진입 준비를 한다.

▽결과를 PredictGesture()에 전달하면 어떤 제스처가 감지됐는지에 대한 인덱스가 전달된다.

▽인덱스가 3보다 작으면 유효한 인덱스이므로 shuold_clear_buffer플래그를 true로 설정한다

void loop() {
  // 가속도계에서 새 데이터를 읽는다.
  bool got_data = ReadAccelerometer(error_reporter, model_input->data.f,
                                    input_length, should_clear_buffer);
  // 버퍼 삭제 시도 X
  should_clear_buffer = false;
  // 새로운 데이터가 없다면 대기
  if (!got_data) return;
  // 추론 실행 및 오류 보고
  TfLiteStatus invoke_status = interpreter->Invoke();
  if (invoke_status != kTfLiteOk) {
    error_reporter->Report("Invoke failed on index: %d\n", begin_index);
    return;
  }
  // 예측 결과 획득
  int gesture_index = PredictGesture(interpreter->output(0)->data.f);
  // 데이터를 읽을 때 버퍼를 비운다.
  should_clear_buffer = gesture_index < 3;
  // 출력을 생성한다.
  HandleOutput(error_reporter, gesture_index);
}

 

▶ main.cc

 

▽함수를 시작하고 setup(), loop() 함수를 실행한다.

#include "tensorflow/lite/micro/examples/magic_wand/main_functions.h"

int main(int argc, char* argv[]) {
  setup();
  while (true) {
    loop();
  }

 

▶ 프로그램 빌드 및 실행

make -f tensorflow/lite/micro/tools/make/Makefile magic_wand
./tensorflow/lite/micro/tools/make/gen/osx_x86_64/bin/magic_wand

 

다음장에서는 MCU에 코드를 이식시킨 후 실행시켜보자.

 

 

반응형

댓글