Running TensorFlow Lite for Microcontrollers on MicroPython. (Trial and Error Edition)
さて。前回の記事では、MicroPython で TensorFlow Lite のモデルをそのまま動かすという、tensorflow-micropython-examples プロジェクトを紹介しました。プリビルドファームウェアをフラッシュメモリに書き込むところまで、なんとかできました。
さて、今回はその動作確認をしてみましょう。
前回は MicroPython のブートまで進みましたが、今回はとりあえず MicroPython の camera モジュールがインポート(import)できるかどうか、確認します。
えいっ。
>>> import camera
Traceback (most recent call last):
File "", line 1, in
ImportError: no module named 'camera'
がーん。import できないではないですか!
MicroPython のマニュアルを参考にし、組み込まれている(import できる)モジュールのリストを表示してみます。
>>> help('modules')
__main__ framebuf uasyncio/lock upip_utarfile
_boot gc uasyncio/stream uplatform
_onewire inisetup ubinascii urandom
_thread math ucollections ure
_uasyncio microlite ucryptolib uselect
_webrepl micropython uctypes usocket
apa106 neopixel uerrno ussl
btree network uhashlib ustruct
builtins ntptime uheapq usys
cmath onewire uio utime
dht uarray ujson utimeq
ds18x20 uasyncio/__init__ ulab uwebsocket
esp uasyncio/core umachine uzlib
esp32 uasyncio/event uos webrepl
flashbdev uasyncio/funcs upip webrepl_setup
microlite や ulab モジュールはちゃんと入っているのに、camera モジュールがありません。。。
メンテナーの方に問い合わせてみる
GitHub の issues ページで質問してみたところ、このプロジェクトの ESP32 camera 版メンテナーと思しき Uli Raich さんから助言を頂きました。詳しくはこちらの Q&A を御参考頂きたいのですが、どうも、tensorflow-micropython-examples のバイナリ配布 MicroPython ファームウェアで、camera モジュールがうまく組み込まれなくなってしまっているようです。(Uli Raich さんが最後にメンテしたのは今年 2022年の 1月末くらいで、それ以降はメンテできていないぽい。)
Raich さんから「最新の MicroPython との互換性が壊れてしまっているので、いろいろトリッキーなんだけど、とりあえず自分でファームウェアをコンパイルしてみてくれますか?」という回答があったので、自分でコンパイルしてみることにしました。いま考えると、別に最新の MicroPython じゃなくてもいいんだけどな、と思うのですが、Raich さにも頻繁にメンテナンスしているお時間がないようなので、とりあえず自分でやってみることにした次第です。
一発ではうまくいかず、何度かやり取りをしたのですが、なんとか動くようになったので、以下に作業をまとめておきます。御参考になれば幸いです。
自力ビルド説明
自力ビルドの方法は、Uli Raich さんが書かれた以下のドキュメント(TWiki だー、懐かしい)に説明されていますが、若干説明不足があるので、補足しながら以下に説明します。
esp-idf の準備
tensorflow-micropython-examples の ESP32 ファームウェアをビルドするには、Espressif 社の開発ツール esp-idf のインストールが必要です。Windows、macOS、Linux で利用できますので、これは皆様各自でインストールしてください。どうしても不明な点があれば、本ページ末尾のお問い合わせフォームから御連絡ください。
インストール方法は以下にあります。なお、esp-idf のバージョンは、Uli Raich さんが利用している v4.3.1 に合わせることにします。
余談ですが、私は pyenv virtualenv の中でビルドしようと思ったのですが、esp-idf は通常(?)の virtualenv を使うことを前提としていて、私の知識では pyenv とはうまく連携できそうにありませんでした。しょうがないので、pyenv global で特定のバージョンの Python(私の場合は 3.9.11)を選んで、その上でビルドすることにしました。
インストールしたら、idf.py
が動くことを確認しておいてください。
ソースコードの展開
まず、tensorflow-micropython-examples を GitHub repo からチェックアウトします。
bash$ export top=$HOME/dokoka # 任意のディレクトリ
bash$ mkdir -p $top
bash$ cd $top
bash$ git clone https://github.com/mocleiri/tensorflow-micropython-examples tflite-micro-micropython
加筆(2023年4月29日〜5月6日)
最新のバージョンだと、以下の手順でうまくビルドできないかも知れません。私の試したバージョンは、2c4573dbaf41dd391a15276bbe4bd9368ae169c4 ですので、git clone のあと、
bash$ cd tflite-micro-micropython
bash$ git checkout 2c4573dbaf41dd391a15276bbe4bd9368ae169c4
して頂きますと、私と同じバージョンで御評価頂けるのではないかと思います。
なお、このブログを御覧になった方から、一点情報を頂きました。このビルド作業では、PC のメモリが 2GB では不足で、4GB 程度は必要のようです。ビルド時にエラーになる場合は、メモリサイズも御確認ください。
必要な(ホスト用)Python モジュールのインストール
Pillow と Wave が必要だそうです。
bash$ pip3 install Pillow Wave
git submodule update
Git のサブモジュールを展開します。
bash$ cd tflite-micro-micropython # 上記で clone したディレクトリです
bash$ git submodule init
bash$ git submodule update --recursive
ディレクトリ microlite/tfm の再構築
この辺はよく分かってません。Raich さんのドキュメント通りです。
bash$ cd tensorflow
bash$ ../micropython-modules/microlite/prepare-tflm-esp.sh # 少し時間がかかります。1〜2分?
最新の MicroPython ソースコードの展開
最新、、、と言いたいところですが、皆様がお試しになる時期によっては、また動かなくなってしまう可能性があるので、以下の Git コミット ID を御利用いただいたほうが確実でしょう。
bash$ cd ..
bash$ rm -rf micropython
bash$ git clone https://github.com/micropython/micropython.git
bash$ cd micropython
bash$ git checkout bdbc44474f92db19a40b5f710a140a0bf70fb0ec # 最新が良い場合は略
bash$ git submodule update --init lib/axtls
bash$ git submodule update --init lib/berkeley-db-1.xx
最新の ulab の展開
micropython-ulab も同様に作業します。
bash$ cd ..
bash$ rm -rf micropython-ulab
bash$ git clone https://github.com/v923z/micropython-ulab.git
bash$ cd micropython-ulab
bash$ git checkout 5ccfa5cdd9040c2c4219c07b005256427d31ed1c # 最新が良い場合は略
aaEspressif の camera driver を取得
bash$ cd ..
bash$ cd tflm-esp-kernels
bash$ git submodule update --init examples/person_detection/esp32-camera
MicroPython クロスコンパイラのビルド
bash$ cd ../micropython/mpy_cross
bash$ make
コードの手修正
以下の Q&A の私のポストにあるように、ソースに修正をしてください。Raich さんの TWiki ドキュメントも御参考ください。
なお、Python コードの修正は Espressif ESP-EYE ボードを利用するためのものです。(次回説明)
依存関係の解決
よく分かってませんが、以下が必要です。
bash$ cd $top/tflite-micro-micropython/micropython/ports/esp32
bash$ make BOARD= submodules
ファームウェアのビルド
ようやくビルドできます。
bash$ cd $top/tflite-micro-micropython/boards/esp32/MICROLITE_SPIRAM_CAM
bash$ idf.py clean build
ファームウェアの書き込み
前回の説明を参考にして、ESP-EYE ボードをブートモードにします。そして、
bash$ idf.py flash
これで、無事にビルドしたファームウェアを書き込めました。
とりあえず camera モジュールの import
ここから先、カメラによる person detection(人の認識)まではもう少し手数がかかるのですが、とりあえず今回は、camera モジュールが import できるかどうかだけ、確認しておきましょう。
ファームウェアを書き込んだ ESP-EYE をリセットします。シリアルターミナルには、次のような表示が出るはずです。
MicroPython 2c4573d-dirty on 2022-09-26; ESP32-cam module (microlite) with ESP32
Type "help()" for more information.
>>>
camera モジュールをインポートしてみます。
>>> import camera
>>>
お、今度は大丈夫そうです。最後に、カメラを初期化してみましょう。以下は、ESP-EYE の場合です。そうでない場合は、こちらを参考にしてください。(カメラが OV2640 か OV3660 で、SPI バスで繋がっている場合には、ここにない ESP32 ボードでも、引数の変更でなんとかなるかも知れません。)
>>> camera.init(0,format=camera.GRAYSCALE,framesize=camera.FRAME_96X96,
... sioc=23,siod=18,xclk=4,vsync=5,href=27,pclk=25,
... d0=34,d1=13,d2=14,d3=35,d4=39,d5=38,d6=37,d7=36)
E (399819) gpio: gpio_install_isr_service(460): GPIO isr service already installed
True
なんか GPIO 周りでエラーが出てますが、とりあえずカメラの初期化はできているようです。
今日はここまで。おつかれさまでした。