M5StickVを入手したので、独自のモデルを作成し画像認識を試してみました。
V-Training を利用するのが一番お手軽ですが、別の方法を試してみました。
M5StickVではkmodelというフォーマットのモデルを使います。
TensorFlow Liteのモデル(tflite)からMaix Toolboxを使ってkmodelに変換できます。
最初にGCPのAutoML Visionを使ってEdge modelを作成し、tfliteモデルをダウンロードしてkmodelに変換しようとしましたが、以下のエラーが発生しました。
Fatal: expect FLOAT32 tensor but got UINT8, use '--inference_type=FLOAT' when converting via toco.
AutoML Vision Edgeでは、「QUANTIZED_UINT8」の8bit量子化モデルになりますが、それだと駄目らしいです。
次に、Keras組み込みのMobileNet v1を使って転移学習を試してみましたが、kmodel変換時に以下のエラーが出ました。
Layer Pad is not supported: Only paddings of [[0,0],[1,1],[1,1],[0,0]] is supported
パディングに関して、なにか違うみたいです。
結局ネットで調べて、K210で利用可能な学習済みのMobileNet v1をダウンロードしました。
kmodel作成に関して色々制限があるようです。
以下の方針でモデル作成しました。
kmodelを作成したGoogle Colabノートブックが以下です。
https://colab.research.google.com/drive/1aEM8gkJJPnrtLGYR3yDdsWydU01lq9Y9
上記ページは編集・実行不可ですが、「ファイル」>「ドライブにコピーを保存…」 すると各自のGoogleアカウントのGoogleドライブにipynbファイルが保存され、編集・実行ができるようになります。
作成したファイル「model.kmodel」と以下のファイル「boot.py」をSDカードにコピーし、M5StickVに挿して起動します。
画像認識しaccuracyが0.9以上の場合に、異なる色のライトを点灯するようにしました。
アイボを認識すると、赤く点灯
boot.py
import lcd
import image
import time
import uos
import sys
import sensor
import KPU as kpu
import os
fm.register(board_info.BUTTON_B, fm.fpioa.GPIO2)
but_b = GPIO(GPIO.GPIO2, GPIO.IN, GPIO.PULL_UP) #PULL_UP is required here!
#fm.register(board_info.LED_W, fm.fpioa.GPIO3)
#led_w = GPIO(GPIO.GPIO3, GPIO.OUT)
#led_w.value(1) #RGBW LEDs are Active Low
fm.register(board_info.LED_R, fm.fpioa.GPIO4)
led_r = GPIO(GPIO.GPIO4, GPIO.OUT)
led_r.value(1) #RGBW LEDs are Active Low
fm.register(board_info.LED_G, fm.fpioa.GPIO5)
led_g = GPIO(GPIO.GPIO5, GPIO.OUT)
led_g.value(1) #RGBW LEDs are Active Low
fm.register(board_info.LED_B, fm.fpioa.GPIO6)
led_b = GPIO(GPIO.GPIO6, GPIO.OUT)
led_b.value(1) #RGBW LEDs are Active Low
lcd.init(freq=15000000)
lcd.rotation(2) #Rotate the lcd 180deg
sensor.reset() # Reset and initialize the sensor. It will
# run automatically, call sensor.run(0) to stop
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000) # Wait for settings take effect.
sensor.set_windowing((224, 224)) # zoom in on the center of the lens
clock = time.clock() # Create a clock object to track the FPS.
lcd.clear()
lcd.draw_string(70, 20, "aibo:Red")
lcd.draw_string(70, 40, "siba:Green")
lcd.draw_string(70, 60, "koma:Blue")
labels = ["aibo", "siba", "koma"]
leds = [led_r, led_g, led_b]
task = kpu.load("/sd/model.kmodel")
while(True):
clock.tick()
img = sensor.snapshot()
fmap = kpu.forward(task, img)
plist = fmap[:]
pmax = max(plist)
max_index = plist.index(pmax)
fps =clock.fps()
lcd.display(img)
print("%s (%.2f), fps:%2.1f" % (labels[max_index], pmax, fps))
for i, led in enumerate(leds):
if i == max_index and pmax > 0.9:
led.value(0)
else:
led.value(1)