ESP32は深い学習の夢を見るか?[4](画像データを作成して人形を認識してみた)


目的

 DeepLearningやっているというのなら、自前で画像データ作って学習しなくちゃ、通とは言えないよね。
 何か対象になりそうな物はないかな。(周りをきょろきょろ)
 おう、目の前にエキストラになってくれそうな人形たちが居るじゃありませんか。(フィギャじゃ無いよ)
 ◆◆◆ そうだ、この人形たちを画像認識するぜ ◆◆◆
 果たしてESP32は、人形を認識してくれるでしょうか。

経緯

 (1)前前回でMNISTデータの処理はつつがなく旨くいってしまった。
 (2)これに味を占めて、今度は自前データを作成してDeepLearningを実行する。
 (3)処理を今一理解してい無いので、分類数は10個。(学習はMNISTと同じ)
 (4)画像データはESP32にカメラを接続して撮影。(カメラの接続に一番手間取った)
 (4)縦横28x28dot、8bitカラーのpngファイルを大量に作成。
 (5)MNISTではtraining用に6000個/種類のデーターを用意しているが、とても無理なので50個/種類で我慢。
  ※果たして正しく認識してくれるのだろうか、ちょこっと心配ではあるが。
 (6)NeuralNetworkConsoleに読み込ませるCSVファイルの作成する。
 (7)NeuralNetworkConsoleで学習を実施し、学習結果の確認とc_sourceの作成を行う。
 (8)評価用画像ファイルとして**.pngを**.binに変換し、ESP32のspiffsに格納。
 (9)c_sourceを多少変更し、コンパイルを行いESP32に読み込ませ実行。結果は如何。

前提条件(前前回と同様)

 以下のソフトを予め導入の事。
 (1)neural_network_console (当たり前、for Windows 8.1/10_64bit 1.4.0にて検証)
 (2)ESP-IDF         (ESP32の開発環境)
 (3)visualstudio(2017)    (一応EXEもアップしたが、ツールを再コンパイルする場合は必要)

ESP32へのカメラの接続

 <ハード>
 下記の信号ライン、電源ラインの計18本を繋げばたいがい動く。(Y0,Y1は繋がない)
 心配であればTTGO-Camera(技適有)等を購入して、まずカメラの動作確認をすべし。
 ※ソフトとピン配置が異なる場合は、信号ラインをmenuconfigで変更する。
 ※下記の配線はESP32_CAMERA_QRに合わせており、いずれのハードでもカメラは動作すると思う。

    # 信号ライン(Pin Configuration)
    CONFIG_D0=5
    CONFIG_D1=18
    CONFIG_D2=19
    CONFIG_D3=21
    CONFIG_D4=36
    CONFIG_D5=39
    CONFIG_D6=34
    CONFIG_D7=35
    CONFIG_XCLK=0
    CONFIG_PCLK=22
    CONFIG_VSYNC=25
    CONFIG_HREF=23
    CONFIG_SDA=26
    CONFIG_SCL=27
    CONFIG_RESET=32
    #電源ライン他
    VCC  3.3V
    GND  GND
    PWDN  GND(パワーダウン信号)

 当方は、ESp32は「ESP32s」の名称で売られているのをamazonで購入。(小さい字で技適のマーク付き)
 カメラは「OV2640 2Mp HD CMOS Camera Module /w Adapter Board」をebayで購入。(同仕様なものが秋月に有り)

 ESP32は大ぐらいで、WiFi初期化時にキャリプレート動作を行った場合、レギュレーター/USB電源が過負荷になるようだ
これが原因でBrownout(低電圧)が発生しリスタートする場合、下記のような対応策がある。
 (1)USBの配線を強化(太く)する。※USBの配線を変えたらBrownoutが発生した事有り。
 (2)電源(5V/3.3V)にコンデンサー(500uF/16Vぐらい)をかませる。
 (3)ESP-IDFのバージョンを上げる。※3.2に上げたら大幅に改善した。が、今度はcomponent.mkの動作が...。
 (4)起動するまでアンテナ部分に手でさわっておく。(起動したら離していい)

 <ソフト>
 カメラ付きESP32を購入した場合は、そのカメラ対応のソフトを探して動作確認をしておくと安心できる。
 当方は別々に購入したモジュールをESP32_CAMERA_QRと同一配線とし、それ用のソフト「ESP32_CAMERA_QR」で動作確認した。
 下記に動作確認済みのソフトを格納しています。必要なら使用の事。
  Camera Demo For ESP32-NNC
 なお、各自によって動作環境が異なりますので、下記はmenuconfigを実行し、sdkconfigを変更の事。

    # ESP32 Camera Demo Configuration
    CONFIG_WIFI_SSID="YourSSID"    ← 各自のSSIDを入れる。
    CONFIG_WIFI_PASSWORD="YorPASSWD"  ← 各自のpasswdを入れる。
    CONFIG_WIFI_IP="192.168.0.90"   ← DHCPの場合は空白にする。固定IPにする場合は各自のIPを入れる。
    CONFIG_WIFI_GW="192.168.0.1"    ← DHCPの場合は不要。固定IPの場合はゲートウェイIPを入れる。
    CONFIG_WIFI_MASK="255.255.255.0"  ← DHCPの場合は不要。
    # Serial flasher config
    CONFIG_ESPTOOLPY_PORT="COM6"    ← 各自の接続番号に合わせる。

画像の収集とCSVファイルの作成

 <画像の収集>
 画像収集ソフトを使用して、指定フォルダ(TestData)以下に画像ファイルを格納する。
 (1)まず、ブラウザで「HTTP://ESP32のアドレス/jpg」の指定を行い画像が出る事を確認しておく。
 (2)[ESP32_CAMERA_QR]の CAMERA_PIXEL_FORMAT を CAMERA_PF_GRAYSCALEに変更。
 (3)[ESP32_CAMERA_QR]の CAMERA_FRAME_SIZE を CAMERA_FS_QQVGAに変更。
 (4)コンパイルしてESP32の動作を開始させる。
 (5)画像収集ソフト(下記)を起動し、「画像読込」を選択。
 (5)指定した周期で画像が読み取られ、指定フォルダにxx_nnn.png(nnnは連番)として格納される。

 
 NeuralNetworkConsoleに読み込ますインデックス(CSV)ファイルを作成する。
 (1)画像収集ソフトで「CSV作成」を選択する。(操作はこれだけ)
  画面で指定したフォルダに、TestData_training.csvとTestData_test.csvが作成される。
  ※ディフォルトでは9(training):1(test)の比率となる。

 上記操作を行った結果を下記に圧縮して格納した。
 取り合えず参考にするなら、適当なフォルダに解凍して、NeuralNetworkConsoleのDATASETで読み込んで使ってみて。
  テストデータ(人形x10x50)

 <画像収集ソフトの機能解説>
   画像収集ソフトの格納場所
  ※例のごとくプログラム部分(EXEは入れた)しかアップしないので、vs2017(VB)でプロジェクトを新規作成して本プログラムを上書き。
  URL :  ESP32のURLを記載
  Dir :  起動時のフォルダを表示(ここを基準にデータが作成される)
  File : データを格納するフォルダ
   TestData : データを格納するフォルダ
   0     : データを格納するサブフォルダ、画像記録時に0-9に順次書き換える
   capture.png : 格納するファイル名、連番の場合はcapture_nnn.pngとなる
  周期 : 画像を読みだす周期(単位ms)
  格納 : チェックしていると、画像を格納する。
  連番 : チェックしていると、画像を連番で格納する。
  有効 : チェックしていると、ESP32側で特定ピン(設定はGPIO15)をLo(0V)にした時のみ画像を格納する
   ※これをチェックしGPIO15とGND間に押しボタンを付けると、押したときのみ格納されるようになる。
  割合 : 「CSV作成」時のtrainingとtestとの割合
  ラジオボタン : 画像の処理モード(現在の設定以外で動作する保証なし)
  画像上段左 : 28x28画像を拡大して表示。(粒子が荒くなっていることが判る)
  画像上段右 : 28x28の実物サイズの画像
  画像下段 : 撮影したQQVGA画像

neural_network_consoleでの操作

 上記で作成したデータを使う以外はプログラムは前前回とほぼ同様。
 但し、CONFIGでBatchSizeを小さく(例えば32)しないとエラーになる。※データ量が少ないため。

テスト画像の変換と格納

 ESP32側でEVALUATIONする場合、それ用の画像(bin)が必要となる。
 この為、TestData_test.csvに記載の画像ファイル(png)を、float(bin)に変換する必要が有る。
 変換処理プログラムはほぼ前々回と同様。追加として最上段にフォルダを指定「一括」を押すと纏めて変換するようにした。
 ※テストデータを変換後、CSVリストの1-8のファイルはDoll_01(?).bin - Doll_08(?).binとリネームしている。(?はdollの撮影順序)
 ESP32への格納方法も前々回と同様。データを追加して格納処理を実行。
 ※データ格納処理を下記にアップ。(テスト用画像ファイルを追加している)
  データ格納処理

ESP32によるEVALUATION

 ESP32のesp-idfでコンパイル可能な形で下記に格納している。
   ESP32によるEVALUATIONソフト
 ※前回プログラムとの共用を図っているため、プログラムの移動が必要となっています。
 (1)esp-nnc main 内のcomponent.mk以外をすべて削除
 (2)eps-nnc main_dollのプログラムを esp-nnc main に全てコピー
 (3)make cleanを実行後、make flash monitorを実行する。
 (4)下記が表示されれば成功。(Good Luck)

    Start
    Spiffs.Dir.Info
     :
     Doll_01(9).bin
     Doll_02(2).bin
     Doll_03(2).bin
     :
    Partition size: total: 956561, used: 245729

    Doll_01(9).bin  +0.258 +0.587 +0.319 +0.338 +0.368 +0.283 +0.358 +0.123 +0.126 +0.959 ( 9 )
    Doll_02(2).bin  +0.291 +0.254 +0.953 +0.785 +0.030 +0.148 +0.258 +0.875 +0.055 +0.291 ( 2 )
    Doll_03(2).bin  +0.236 +0.282 +0.945 +0.817 +0.049 +0.153 +0.243 +0.810 +0.062 +0.379 ( 2 )
    Doll_04(3).bin  +0.199 +0.340 +0.836 +0.940 +0.086 +0.486 +0.077 +0.175 +0.244 +0.347 ( 3 )
    Doll_05(8).bin  +0.499 +0.242 +0.045 +0.105 +0.619 +0.896 +0.548 +0.163 +0.890 +0.110 ( 5 )
    Doll_06(0).bin  +0.965 +0.232 +0.261 +0.234 +0.223 +0.311 +0.304 +0.299 +0.614 +0.232 ( 0 )
    Doll_07(6).bin  +0.222 +0.203 +0.296 +0.141 +0.137 +0.392 +0.962 +0.170 +0.226 +0.295 ( 6 )
    Doll_08(3).bin  +0.199 +0.326 +0.836 +0.939 +0.082 +0.486 +0.079 +0.173 +0.240 +0.332 ( 3 )
    Stop

EVALUATION結果の評価

 枚数も少なくいい加減な撮影にもかかわらず、ほぼ正解となっている。
 ただ、撮影がいい加減なので、正解以外でも数値が上昇しいると思われる。
 Doll_05(8).binは(正解8を5と)誤回答だが、画像を見ると上半分しか映っていない。
 それでも5が+0.896、8は+0.890の評価であり、もう少しうまく写っていれば正解となるだろう。
 しかし、私が画像を見ても区別が...、DeepLearningは何処を見て判断しているのだろうか。

 意外といい結果が出たので、もう少し真っ当に撮影し枚数も増やして結果を確認すべきと考える。
 但し、training用とTest用の画像は同時期に撮影しており、撮影条件を変えると正解率が低下するとも思われる。
 この流れからして、次はカメラ画像をDeepLearningに直接取り込んで、リアルタイム画像認識に迫ることになりそう。
 なお、もし追試する奇特な方がおられた場合、上記記載内容は無保証であり、各自の責任においてご利用願います。