#はじめに
失敗談です。解決策を求めてきた方はそっとタブを閉じてください。
同じことをやろうとした人がいたら情報交換したいと思って書きました。
※このまえ熊本のイベントで話した内容です。
ちょっと前に中国の深圳のスタートアップ企業であるSipeedから激安なAI向けのボードが発売されました。
- RISC-V x2
- KPU(ニューラルネットワーク処理
- カメラ
- ディスプレイ
- マイク
- オーディオアンプ
など色々ついてて2800円です。(スイッチサイエンスはもう少し高い)
#Sipeed MAixシリーズはShigezone開店当初からの人気製品。特に人気なのはESP32やDAC、3Wオーディオアンプを搭載した「MAixduino」です。
— Shigezone〜深圳直送便〜電子部品&機器のお店:秋葉原ラジオデパート3F (@ShigezoneAkiba) July 8, 2019
液晶とカメラまでセットで税込3,500円です。
店頭販売のほか、多数まとめてのご購入や製品組込のコンサルティング・製造など、お気軽にご相談ください。 pic.twitter.com/NVeBFrEtqm
5月末にマイクロソフトのde:codeの帰りに、秋葉原のShigezoneで購入しました。ここは深圳から仕入れた面白怪しいものを破格の値段で買えるのでお勧めです。
私が買ったのはSipeed Maix M1 Dockです。Wifiのモジュールもありますが技適ががが。
技適付きがいいならSipeed Maixduinoを買うといいです。
細かい説明は他の方が書いてるので省きますが、これだけ安いボードでAIを動かせるとなると自分でいろいろと動かしたくなるわけです。
参考:Sipeed M1 dockを動かしてみた
#【理想】楽にAIやりたい
AIに関してはTensorFlowを一通りやったくらいです。あとはAzureのCognitive Servicesをよく使ってます。最近だとCustomVisionを使ってアナログメータ(湿度計)の読み取りとかやってました。
##CustomVisionのモデルをSipeedに持っていきたい
ざっくりしたイメージはこんな感じです。
CustomVisionで作成したモデルをエクスポートして、kmodelへ変換してsipeedに持っていくというものです。
##先に結論を言うと
TensorFlow Liteからkmodelへ変換する際にエラーとなり詰みました。エラーは下記のような感じ。
/content/Maix_Toolbox
Fatal: Layer tflite.Operator is not supported: Only scalar multiply is supported
NnCase.Converter.Converters.LayerNotSupportedException: Layer tflite.Operator is not supported: Only scalar multiply is supported
at NnCase.Converter.Converters.TfLiteToGraphConverter.ConvertMul(Operator op) in D:\Work\Repository\nncase\src\NnCase.Converter\Converters\TfLiteToGraphConverter.cs:line 243
at NnCase.Converter.Converters.TfLiteToGraphConverter.ConvertOperator(Operator op) in D:\Work\Repository\nncase\src\NnCase.Converter\Converters\TfLiteToGraphConverter.cs:line 79
at System.Linq.Enumerable.SelectEnumerableIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at NnCase.Converter.Converters.TfLiteToGraphConverter.Convert() in D:\Work\Repository\nncase\src\NnCase.Converter\Converters\TfLiteToGraphConverter.cs:line 34
at NnCase.Cli.Program.Main(String[] args) in D:\Work\Repository\nncase\src\NnCase.Cli\Program.cs:line 113
at NnCase.Cli.Program.<Main>(String[] args)
では、やったことを書いておこうと思います。
##CustomVisionからモデルを引っこ抜く
CustomVisionでドメインをcompactにして学習させた後、TensorFlowとしてエクスポートします。
今回は簡単に5種類の食べ物を分類するモデルを作りました。
- model.pb
- labels.txt
エクスポートするとTensorFlowのPBファイルとラベルのテキストファイルがダウンロードできます。
##TensorFlowからTensorFlow Liteへ変換
kmodelへの変換ツールはGitで公開されています。
さらにkmodelへ変換するための参考となる情報も公開されてます。
###CustomVisionのPBファイルの中を確認
変換するために必要なパラメータをtensorboardで確認します。
pbファイルを置いた場所で下記を実行(なぜかColaboratoryがうまく動かなかったのでここはAnacondaのjupyterでやりました)
import tensorflow as tf
from tensorflow.python.platform import gfile
with tf.Session() as sess:
model_filename ='./tensorflow_inception_graph.pb'
with gfile.FastGFile(model_filename, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
g_in = tf.import_graph_def(graph_def)
LOGDIR='LOGDIR'
train_writer = tf.summary.FileWriter(LOGDIR)
train_writer.add_graph(sess.graph)
上のpythonのコードを実行するとLOGDIRというフォルダができると思うので、この階層で下記のコマンドを実行します。
tensorboard --logdir=LOGDIR
そうすると上の画像の一番下にあるようにURLが発行されるのでアクセスする。
Main Graphのimportの中の出力層と入力層を調べます。
赤枠で囲ったところ3つをメモしておきます。
###PBファイルからTFLITEへ
ここからはGoogleのColaboratoryで作業してます。
参考:Maixpy GO Mobilenet Transfer learning for Image Classfication
#変換用のtoolをclone(先頭の「!」はColaboratoryでのお作法)
!git clone https://github.com/sipeed/Maix_Toolbox.git
cloneしたら、
#変換用のフォルダ作成と解凍作業
%%bash
cd Maix_Toolbox
mkdir -p ncc
mkdir -p workspace
mkdir -p images
mkdir -p log
cd ncc
wget https://github.com/kendryte/nncase/releases/download/v0.1.0-rc5/ncc-linux-x86_64.tar.xz
tar -Jxf ncc-linux-x86_64.tar.xz
rm ncc-linux-x86_64.tar.xz
echo "download nncase ok!"
モデルをアップロード(ドライブにフォルダ作ってマウントしてもどっちでもよいです)
toolboxのworkspaceにコピーして変換
!cp model.pb Maix_Toolbox/workspace/model.pb
!cp labels.txt Maix_Toolbox/workspace/labels.txt
%cd Maix_Toolbox
#pb -> tflite
!toco --graph_def_file=workspace/model.pb --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --output_file=workspace/model.tflite --inference_type=FLOAT --input_type=FLOAT --input_arrays=Placeholder --output_arrays=model_outputs --input_shapes=1,224,224,3
- input_arrays:Placeholder
- output_arrays:model_outputs
- input_shapes:1,224,224,3
この3つのパラメータはtensorboardでメモした値です。
これでtfliteに変換完了です。
%%bash
cd /content
mkdir /content/test_photos/cake
mkdir /content/test_photos/curry
mkdir /content/test_photos/pizza
mkdir /content/test_photos/sandwich
mkdir /content/test_photos/sushi
フォルダを作成する。
テスト用の画像をアップロードして、このフォルダ移動していく
#foodのテスト画像(ファイル名はご自身のものに適宜変えてください)
!mv /136149.jpg /content/test_photos/cake
!mv /176394.jpg /content/test_photos/cake
!mv /42503.jpg /content/test_photos/cake
!mv /908125.jpg /content/test_photos/cake
!mv /91387.jpg /content/test_photos/cake
!mv /1225331.jpg /content/test_photos/curry
!mv /1251235.jpg /content/test_photos/curry
!mv /1285185.jpg /content/test_photos/curry
!mv /834077.jpg /content/test_photos/curry
!mv /949975.jpg /content/test_photos/curry
!mv /289265.jpg /content/test_photos/sandwich
!mv /326580.jpg /content/test_photos/sandwich
!mv /335343.jpg /content/test_photos/sandwich
!mv /360537.jpg /content/test_photos/sandwich
!mv /366787.jpg /content/test_photos/sandwich
!mv /1025041.jpg /content/test_photos/sushi
!mv /1098082.jpg /content/test_photos/sushi
!mv /377047.jpg /content/test_photos/sushi
!mv /638929.jpg /content/test_photos/sushi
!mv /723084.jpg /content/test_photos/sushi
最後にkmodelへの変換を実行し・・・エラーとなるorz
%cd /content/Maix_Toolbox
!./ncc/ncc -i tflite -o k210model --dataset /content/test_photos /content/Maix_Toolbox/workspace/model.tflite /content/Maix_Toolbox/workspace/model.kmodel
Fatal: Layer tflite.Operator is not supported: Only scalar multiply is supported
というエラーなわけですが、調べてみたらどうやらKmodelへの変換に際し、レイヤーの制限があるらい
参考:nncase
問題はここからどうやってトレースすればいいのかTensorflowをちょっとかじった程度の人間にはわからず、そもそもモデルはAzure側で作成してる以上PBファイルの修正なんてできないのでここでgame overとなりました。
初めての試みなので、そもそもどこか途中で間違ってて実はうまくいくという可能性もゼロではないですが、もし同じようなことをして成功したという方がいればぜひ情報交換したいです。
ちなみに最近発売されたM5StickVもおなじKPUを搭載していて、Sipeedとほぼ同じ開発手順で開発できるので基本的にはSipeedで出来ることはM5StickVにも応用できると思います。