Magicode logo
Magicode
8 min read

raspberry pi picoでtensorflow lite microのHello Worldをやってみた

https://cdn.apollon.ai/media/notebox/98a1dbba-991d-4345-8ecc-1ca0b0b77fc5.jpeg

はじめに

raspberry pi pico(以下、pico)上でTensorflow Lite for Microcontrollersを動かしてみた。

環境

Tensorflow Lite for Microcontrollersとは

概要

公式ドキュメントではこのように説明されている。
TensorFlow Lite for Microcontrollers は、メモリが数キロバイトしかないマイクロコントローラなどのデバイス上で機械学習モデルを実行するように設計されています。コアランタイムは Arm Cortex M3 で 16 KB に収まり、さまざまな基本的モデルを実行できます。オペレーティング システムのサポート、標準の C / C++ ライブラリ、動的メモリ割り当ては必要ありません。
リソースの限られているマイコン上で機械学習モデルを実行するためのライブラリ
あくまで 実行するため なのでマイコン上で学習せず、PC上で学習した結果を流用して推論器を動かすことになる。

対応プラットフォーム

2022/05/09現在では、12個の開発プラットフォームに対応している。(あれpicoがみあたらない)
  • Arduino Nano 33 BLE Sense
  • SparkFun Edge
  • STM32F746 Discovery kit
  • Adafruit EdgeBadge
  • Adafruit TensorFlow Lite for Microcontrollers Kit
  • Adafruit Circuit Playground Bluefruit
  • Espressif ESP32-DevKitC
  • Espressif ESP-EYE
  • Wio Terminal: ATSAMD51
  • Himax WE-I Plus EVB Endpoint AI Development Board
  • Synopsys DesignWare ARC EM Software Development Platform
  • Sony Spresense

ワークフロー

大きな流れとしては下記の二つ。
  1. PC上でモデルをトレーニング
  2. デバイス上で推論
ただ、当然、1の前で学習用データの収集・(マイコン上で動かせる演算かつ小さな)Tensorflowモデルの設計が必要。
また、トレーニング結果をマイコンで動かすためのツール(Tensorflow Lite コンバーター)による、変換も必要。

制限事項

公式ドキュメントより
  • TensorFlow オペレーションの一部しかサポートされていない
  • デバイスの一部しかサポートされていない
  • 低レベルの C++ API では手動でのメモリ管理が必要となる
  • デバイス上でのトレーニングはサポートされていない

picoで動かすには?

ラズパイ財団がgithubにあげてくれている。

動かしてみる

clone してビルド!

picoの環境構築は以前の投稿を参照。
環境構築ができていたら、cloneして、ビルドするだけ。
・・・のはずだが、ビルドエラー
[  5%] Linking CXX executable hello_world_test.elf
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj: in function `main':
util_test.cpp:(.text.startup.main+0x0): multiple definition of `main'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:hello_world_test.cpp:(.text.startup.main+0x0): first defined here
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj:(.bss._ZN10micro_test8reporterE+0x0): multiple definition of `micro_test::reporter'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:(.bss._ZN10micro_test8reporterE+0x0): first defined here
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj:(.bss._ZN10micro_test13did_test_failE+0x0): multiple definition of `micro_test::did_test_fail'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:(.bss._ZN10micro_test13did_test_failE+0x0): first defined here
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj:(.bss._ZN10micro_test16is_test_completeE+0x0): multiple definition of `micro_test::is_test_complete'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:(.bss._ZN10micro_test16is_test_completeE+0x0): first defined here
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj:(.bss._ZN10micro_test12tests_failedE+0x0): multiple definition of `micro_test::tests_failed'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:(.bss._ZN10micro_test12tests_failedE+0x0): first defined here
c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/hello_world_test.dir/__/__/src/tensorflow/lite/micro/testing/util_test.cpp.obj:(.bss._ZN10micro_test12tests_passedE+0x0): multiple definition of `micro_test::tests_passed'; CMakeFiles/hello_world_test.dir/hello_world_test.cpp.obj:(.bss._ZN10micro_test12tests_passedE+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
NMAKE : fatal error U1077: 'C:\PROGRA~2\GNUARM~1\102021~1.10\bin\AR10B2~1.EXE' : リターン コード '0x1'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86\nmake.exe"' : リターン コード '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86\nmake.exe"' : リターン コード '0x2'
Stop.

とりあえずhello worldを動かす

ビルドターゲットを hello world のみ指定すればビルドできる。(下図の歯車アイコン右の all をクリックして検索ウィンドウからhello worldを選択する。)
hello worldでは、正弦関数を学習したモデルを利用しているようで、マイコンに書き込むとLEDが点滅する。
Hello Worldの例は、マイクロコントローラーにTensorFlowLiteを使用するための絶対的な基本を示すように設計されています。正弦関数を複製するモデルをトレーニングして実行します。つまり、単一の数値を入力として受け取り、その数値の正弦値を出力します。マイクロコントローラーに展開されると、その予測はLEDを点滅させるか、アニメーションを制御するために使用されます。

状況

ぱっと検索した感じでは対応方法が見当たらなかった。(2022/05/04)
疲れていたので動かすことを優先し、hello worldのみビルドして動かした。
githubのリポジトリがreadonlyでissueが作れなかったので、問い合わせは保留にした。

終わりに

時間の都合で、原因追及まではできなかった。今後きちんと調べたい。
コンソール出力でtestという単語が見当たるので、testコード周りについてみてみようかと思う。
また、前回の投稿で加速度センサーを使っているので、magic wandも動かしてみたい。
ただ、ドキュメントには、具体的にどうしろという記述はない。
こちらの記事はちょっと古いのと、M5Stack Fireへの移植になってしまいますが、参考になりそう。
下記のように、accelerometer_handler.ccで自分が使う加速度センサの読み取り処理を書いて、output_handler.ccで推論結果をどう扱うか書けばよさそう。
このデモのコードは、加速度センサの読み取りをaccelerometer_handler.cc、検出結果の処理をoutput_handler.ccへ実装するような構成になっています。初期状態では、前者はダミーコード、後者は結果をテキストでシリアルポートへ出力するコードになっています。
magic wandに挑戦した記事はこちら

Discussion

コメントにはログインが必要です。