#目的
現在の生活では家電品の操作にはリモコンが必要であり、我が家でもそこら中に氾濫している。
近未来では、見つめるだけでエアコンの電源が入る、テレビのチャンネルが変えられるようになる(かも知れない)。
これを取り合えず実現するには次のような技術が必要だ。
■操作対象の認識 → ■動作の選択 → ■対象へのアクション
(カメラ+画像認識) (加速度センサー) (赤外線信号)
うむ、現状技術でも到達可能な気がする。でも体に付けたいから小さくないとね。
◆◆◆ そうだ、ESP32へDeepLearningを実装したら実現出来るかも。 ◆◆◆
まずは手始めに「アヤメの分類」からでも手を付けてみるか。(今回は画像処理まで行きついていません)
#経緯
(1)ESP32のカメラ接続に技術的な問題が無いので、画像認識方法を考えたい。
(2)ど定番のTensorFlowを乗せるのは、ESP32ではメモリ容量的に無理なのは明らか。
(3)Cで書かれたライブラリを見つけたが、コンパイル結果は16MB程度になったのでちょっと無理と判断。
(4)neural_network_consoleのマイコンへの応用事例が見つかった。小容量でも使えるみたい。
(5)CQ出版 Interface 2019年 1月号及びQiita等の事例では、インプリメント部分の説明不十分(私的には)。
(6)ESP32の事例も有ったが、前提とする条件が複雑であり、うまく追試をやれる自信なし。
(7)仕方が無いので、事例から情報を読み取り、いろいろ試してみたら、「アヤメ」は案外うまくいった。
#neural_network_consoleとは
天下のSONYが無償で公開している(よ、太っ腹)、GUIで操作できる機械学習用ソフト。
今までは、Pythonを入れ手間をかけて環境を整えてやる必要があり、設定同士がぶつかり動作しないことも。
おっとびっくり、これを入れればあっという間に動くものが出来上がり。
[Neural Network Console - Sony] (https://dl.sony.com/ja/)
※処理速度が遅いという噂も有るが、構築のお手軽さを評価すべきで、本質的な部分により力を注げる。
※GPUを搭載しているほうが幸せになれる。
おまけなのか、evaluation(評価)用のCのソースプロクラムを吐き出してくれる。
(マイコン化への貴重なインターフェースだが、説明が少なくSONYとしては力を入れてないのかな)
#前提条件
以下のソフトを予め導入の事。
(1)neural_network_console (当たり前、for Windows 8.1/10_64bit 1.4.0にて検証)
(2)ESP-IDF (ESP32の開発環境)
(3)VisualStudio(2017) (パソコン上で動作確認したい場合に必要、無くても可)
#neural_network_consoleでの操作(アヤメの分類)
(1)下記を実施し、正しくEVALUATIONが行えることを確認する。
[SonnyのNNC(Neural Network Console)でのアヤメの分類の実装] (https://newtechnologylifestyle.net/sonny_nnc_irisdata_junnbi/)
(2)EVALUATION画面で、ACTION → Export → NNB と選択していく。
(3)c_source(マイコン用プログラム)が存在する画面が表示されるので、必要なフォルダにコピーする。
※c_source内のプログラムの機能について(推測)
MainRuntime_example.c mainプログラム、入力、評価、出力を実施。
MainRuntime_inference.c GUIで設定した構成を反映、下位モジュールでDeepLearning処理を行う。
MainRuntime_parameters.c 学習結果を配列として保持。
#neural_network_consoleでのデータ入出力について
c_sourceのMainRuntime_example.cは独自形式の画像入力にのみ対応している。
特定の例題(10_deep_mlp)以外では、別途プログラムによる対応が必要となる。
この部分はかなり曖昧に書かれており、詳細は不明。(説明書が何処かにあるのかも知れないが)
下記のような考えを想定してプログラムしたらうまく動作した。
(1)入出力は単精度実数(float)
※neural_network_consoleではcsvで入力しているが、MainRuntime_example.cではfloatに変換して与える必要有り。
(2)入力する値はinput_bufferがポインタする位置に数値を必要数書込む。
float *idbf = nnablart_mainruntime_input_buffer(context, 0); // Input.Data.Buffer
sscanf(buf, "%f,%f,%f,%f,%f", &idbf[0], &idbf[1], &idbf[2], &idbf[3], &label);
※neural_network_consoleのEVALUATION画面での、x_0,X_1,X_2,X_3に対応するデータを与える。
(3)出力された値はoutput_bufferがポインタする位置に書き込まれている。
float *odbf = nnablart_mainruntime_output_buffer(context, 0); // Output>data.buffer
for (int j = 0; j < 3; j++) printf(" %+.3f", odbf[j]);
※neural_network_consoleのEVALUATION画面での、y_0,y_1,y_2に対応するデータを読みだす。
EDITで、出力に必要とするy_0,y_1,y_2等がEVALUATION画面に表示されるように構成する必要有り。
#ESP32による「アヤメの分類」のEVALUATION(データーファイル不使用バージョン)
※esp32はファイルシステムを使用可能だが、登録処理に多少手間が必要。
そこでデーターをプログラム(**.h)に埋め込み入力データとする。
(1)ライブラリ(nnabla-c-runtime)を取得する。
[nnabla-c-runtime] (https://github.com/sony/nnabla-c-runtime)
(2)ESP32でコンパイル可能なエリアにフォルダ(例:esp-nnc)を作成。
(3)必要なライブラリ(src functions下のimplementsとutilities)をesp-nnc(のcomponents下)に格納
(4)c_sourceの内容をフォルダにコピーする(例ではmain下)。
(5)esp-idfがコンパイルしてくれるように、各フォルダにcomponent.mkを作成、配置。
※esp-idfをバージョンアップしたらコンパイルが通らなくなりました。
component.mkの適用範囲が変わったと思われるので、(バグだと思うが)
component以下のディレクトリをすべて書き込みました。(前のはimplements utilitiesのみ記載)
(6)MainRuntime_example.cを処理内容に合わせて書き換え。
※MainRuntime_example.cの19行目「//#define FINP」はコメント(//)に設定の事。
(7)ESP32メイン(app_main)からMainRuntime_example.cのmain()を呼びだすようにプログラムを作成。
※上記説明だけでは判り難いとおもわれるので、説明も兼ねて(1)-(7)を実施した結果を下記にアップしている。
ダウンロードすればesp32開発環境下でコンパイル可能(なはず)。
[ESP32による「アヤメの分類」] (https://github.com/hi631/esp32-nnc/tree/master/esp-nnc)
(7)make flash monitor を実行。(ctrl+]で終了)
下記が表示されるので、neural_network_consoleの表示と比較する。
※シリアルをCOM6に設定しているので、異なる場合はmake menuconfigで変更するか、COM番号を変更の事。
* Start *
5.0 3.5 1.3 0.3 ( 0 ) +6.443 +2.331 -7.357 ( 0 )
4.5 2.3 1.3 0.3 ( 0 ) +5.065 +2.398 -6.332 ( 0 )
:
6.2 3.4 5.4 2.3 ( 2 ) -4.329 +1.268 +2.976 ( 2 )
5.9 3.0 5.1 1.8 ( 2 ) -3.711 +1.436 +2.227 ( 2 )
* Stop *
#ESP32による「アヤメの分類」のEVALUATION(データーファイル使用バージョン)
ESP32でデーターファイルを使用する場合、spiffsライブラリを使用することになる。
また、予めデータを用意する場合は、エリアの確保、データイメージの作成とアップロード機能が必要となる。
なお、データー格納エリアはpartitions_example.csvに書いており、flashの0x300000から0x3fffff(1MB)を使用している。
<データファイルの作成と格納>
(1)下記をダウンロードし、ESP32でコンパイル可能なフォルダに配置する。
[ESP32_spiffs_example] (https://github.com/loboris/ESP32_spiffs_example)
(2)esp-nnc内のpartitions_example.csvをESP32_spiffs_exampleにコピー。
(2)mingwを起動し、配置したフォルダ内で ./build_mkspiffs を実行。
components mkspiffs 内に mkspiffs.exe が生成される。
※当方の環境では424行でエラーとなったので、「_mkdir」を「mkdir」に変更することで回避。
(3)components spiffs_image image にアップロードするデータファイルを格納。
※samples sample_dataset iris_flower_dataset iris_flower_dataset_validation_delo.csv は iris_flower.csv としている。
(4)make makefsの実行で、イメージファイル(1MB)が作成される。
make flashfsの実行では、イメージファイルの作成後にESP32への転送が行われる。
(5)make flash の実行で、テストプログラムのコンパイルと実行が行われるので、ESP32への格納の確認が可能。
※上記を実施したものを下記に圧縮して格納しているので、必要なら利用の事。
[データファイルの作成と格納用プログラム] (https://github.com/hi631/esp32-nnc/blob/master/spiffs_example.zip)
<実行>
「データーファイル不要バージョン」と操作は同一。
但し、MainRuntime_example.cの19行目「//#define FINP」のコメント(//)は取っておく。
実行時に下記(格納ファイル情報)が追加表示される。
「iris_flower.csv」が表示されない場合は、データファイルの作成と格納に失敗している。
Spiffs.Dir.Info
:
iris_flower.csv
:
Partition size: total: 956561, used: 211091
#VisualStudio(2017)による「アヤメの分類」のEVALUATION
neural_network_consoleで表示されるものをVisualStudioで表示してもあまりメリットを感じないが、、
パソコン上でのプログラムのデバッグには非常に役に立った。
※入出力の確認などは全てVisualStudio上で行った。これをESP32上で行ったら多大の時間を要したはず。
(1)ライブラリ(nnabla-c-runtime)を持ってくる。
[nnabla-c-runtime] (https://github.com/sony/nnabla-c-runtime)
(2)nnabla-c-runtimeフォルダで cmake CMakeLists.txt を実行。
※当方の環境ではesp-idf用に構築したmingw上にcmakeを登録して実行。
複数の前提ソフトが必要となったがなかなか登録できず、一寸大変であった。
(3)nnabla-c-runtime src functions に c_source をフォルダごとコピー
(4)MainRuntime_example.cの書き換えを行う。
(5)nnabla-c-runtime src functions に dataフォルダを作成し、必要とされるデータを入れておく。
(6)nnabla-c-runtime src functions に nnablart_functions.sln が出来ているので起動する。
※visualstudio2017が登録されていたら起動する。(ない場合はどうなるだろう)
(7)nnablart_functions 以外のソリューションは(とりあえず)要らないので削除しておく。
(8)nnablart_functions を右クリック、プロパティ 全般 構成の種類 で アプリケーション (.exe)に変更する。
(9)nnablart_functions を右クリック、スタートアッププロジェクトに設定する。
※上記を実施したものを下記に圧縮して格納しているので、必要なら利用の事。
[visualstudioによる「アヤメの分類」] (https://github.com/hi631/esp32-nnc/blob/master/nnabla-c-runtime.zip)
解凍後は「C:\」に設置し、c:\nnabla-c-runtime src functions の nnablart_functions.sln を起動する。
(visualstudioのslnは絶対ディレクトリとなるため、必ず存在するディレクトリで作成した)
(10)デバッグを開始すればESP32の時と同様な表示が出る。(はず)
なるたけ再現性を確保したつもりですが、ごてごて書くのも何なんで、説明が不十分だと思います。
後はアップロードしているプログラムで内容を確認願います。
次はMNIST(画像による数字認識)に迫りたいと思っている。
上記記載内容は無保証であり、各自の責任においてご利用願います。