オリジナル金魚認識モデルの生成 ーエッジAI活用への道 3ー
さて前回は アライグマの画像データサンプル を用いてMaixduino用の画像認識モデルを製作する手順を学び紹介させていただきました。
ここでは金魚の画像を元に認識モデルを生成して我が家の金魚ちゃんのMaxduinoのカメラでのリアルタイム認識を目指します。
手順としましては前回のアライグマの画像を金魚にしてラベリングし同様に学習しただけですが、改めて順にご説明させていただきます。
目次
金魚画像の準備
我が家のカワイイ金魚(和金)の認識を目指して認識用モデルを作るべく学習用の画像を準備します。赤い和金の画像をGoogleで40個、自分で撮影したものを173個の計213画像 用意しました。
画像のラベリング(アノテーション)
画像の学習には教師データが必要となります。今回は金魚しか認識しませんのでクラスをgoldfishとして画像の一つ一つにどこに金魚がいるかをラベル付けする必要があります。深層学習などではラベル付けをアノテーション作業というようです。
アノテーションはアライグマの画像データサンプル にならってPascal VOC形式(xml)で行います。
ここではアノテーション作業に非常に有用なソフト LabelImg を使用しました。
Virtual Box上のUbuntuにLabelImgをインストールしました。Python3とGUIソフトのQt5を使用します。
1 2 3 4 |
sudo apt-get install pyqt5-dev-tools sudo pip3 install -r requirements/requirements-linux-python3.txt make qt5py3 sudo python3 labelImg.py |
LabelImgの使い方
LabelImgを起動し”Open Dir”で画像が保存先を指定し、”Change Save Dir”でアノテーションデータ保存先を指定します。Use default labelにチェックを入れてモデルのクラス名(goldfish)を記載しておくと便利です。
“Create\nRectBox”をクリックして画像をドラッグして金魚の場所を指定します。
“Save”で以下のようなPascal VOC形式のアノテーションデータが生成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<annotation> <folder>images</folder> <filename>goldfish-51.jpg</filename> <path>/home/hoge/Yolo-digit-detector-goldfish/goldfish_dataset/images/goldfish-51.jpg</path> <source> <database>Unknown</database> </source> <size> <width>600</width> <height>450</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>goldfish</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>31</xmin> <ymin>96</ymin> <xmax>305</xmax> <ymax>250</ymax> </bndbox> </object> <object> <name>goldfish</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>249</xmin> <ymin>137</ymin> <xmax>539</xmax> <ymax>329</ymax> </bndbox> </object> </annotation> |
これをすべての画像に対して実施します。かなり大変ですね。。。。今回は金魚だけ認識するので1クラスで十分ですがいろんなものを識別するモデルを生成するには膨大なデータと手間が必要となりますね。
AIは人間の仕事を奪うといいますが、逆に増やしてはいやしないか。。。とすら思いました。
学習
アライグマの時同様に以下の学習用プロジェクトデータに画像とアノテーションデータをコピーして学習します。
https://github.com/AIWintermuteAI/Yolo-digit-detector
configsフォルダに学習設定jsonファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ "model" : { "architecture": "MobileNet", "input_size": 224, "anchors": [0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828], "labels": ["goldfish"], "coord_scale" : 1.0, "class_scale" : 1.0, "object_scale" : 5.0, "no_object_scale" : 1.0 }, "pretrained" : { "full": "" }, "train" : { "actual_epoch": 30, "train_image_folder": "/home/hoge/Yolo-digit-detector-goldfish/goldfish_dataset/images", "train_annot_folder": "/home/hoge/Yolo-digit-detector-goldfish/goldfish_dataset/annotations", "train_times": 5, "valid_image_folder": "", "valid_annot_folder": "", "valid_times": 1, "batch_size": 4, "learning_rate": 1e-4, "saved_folder": "goldfish", "first_trainable_layer": "", "jitter": true, "is_only_detect" : false } } |
正直この辺の値や正確な意味はよくわかってないです。。。随時理解したら追記したいと思います。
actual_epoch:全体の学習回数
train_image_folder:学習する画像のパス
train_annot_folder:学習画像データのアノテーションデータのパス
train_times:学習サイクル
valid_image_folder、valid_annot_folder:検証用のデータのパス
ここをカラにすると学習用のデータからランダムに2割のデータを検証用
として学習されます。
valid_times:検証回数
batch_size:?
learning_rate:?
saved_folder:?
first_trainable_layer:?
jitter:?
is_only_detect:?
どうしたら効率よく良いモデルができるのかこの辺の設定が要だと思うのですが、じっくり勉強します。
学習開始-モデル生成
以下で設定した条件での学習がスタートします。深層学習ライブラリ Keras + TensorFlowで学習しているようです。
python train.py -c configs/goldfish.json
学習が終了すると、model.tfliteというモデルファイルが生成されます。
学習モデルの変換
生成されたモデルmodel.tflite をMaixduinoでも利用できる.kmodelファイルに変換します。
変換にはSipeed社の提供するMaix Toolboxを使用します。以下をDLします。
https://github.com/sipeed/Maix_Toolbox
DLし展開したら、まず以下を実施して環境を構築します。
bash get_nncase.sh
実行後に生成されるimagesフォルダには入力サイズである224 x 224の画像をいくつか入れておきます。これをしないと変換時にエラーがでます。
https://bbs.sipeed.com/t/topic/569/7
先ほど生成したモデル model.tflite をMaix Toolboxに入れて以下実施で変換開始します。
./tflite2kmodel.sh model.tflite
以上でK210用のmodel.kmodelファイルが生成されました。
ファーム、モデル書き込み
kflash_guiでファームと.kmodelファイルをMaixduinoに書き込みます。
ファームは maixpy_v0.4.0_13_ga40842f.bin を書き込みました。学習モデルmodel.kmodelはアドレス0x600000に書き込みました。
Micropythonコード
コードはYolo-digit-detector/micropython_code/racoon_detector.py を使用します。MaixPy IDEで書き込みました。
また画面方向調整のためコードに以下の挿入・変更施しました。
1 2 3 4 5 6 |
lcd.direction(lcd.YX_RLDU) sensor.set_vflip(0) sensor.set_hmirror(0) classes = ["goldfish"] |
動作
40画像
Googleで和金を検索して40個の画像を取得してモデル生成しました。
とりあえずGoogle上の赤い和金の画像40枚で適当に学習しモデル作った。
検出それなりにできた。
画像200枚にして同様に味見して、それから学習について真面目に学習します。#Maixduino #sipeed #金魚 pic.twitter.com/KDXas1PZdU— HomeMadeGarbage (@H0meMadeGarbage) October 6, 2019
静止画の金魚は認識できましたが水槽の動く金魚の認識はできませんでした。
95画像
水槽の金魚の写真を55枚追加しました。
自宅の金魚画像追加して95画像で再トライ。だんだん良くなってくる♪︎
全部自宅金魚の画像の方がいいかな?#Maixduino #sipeed #金魚 pic.twitter.com/uI6gUofQXu
— HomeMadeGarbage (@H0meMadeGarbage) October 6, 2019
水槽の金魚も何となく認識できるようになってきました。
175画像
更に水槽の金魚の写真を追加
175画像で学習。更にいい感じ#Maixduino #maix #sipeed #金魚 pic.twitter.com/3lNufEKQGz
— HomeMadeGarbage (@H0meMadeGarbage) October 6, 2019
いい感じいい感じ♪
213画像
更に更に水槽の金魚の写真を追加
213画像 そろそろええやろか。めちゃめちゃ動くから難しいね。
元気な金魚ちゃんたち#Maixduino#maix #sipeed pic.twitter.com/w41Df6woB1
— HomeMadeGarbage (@H0meMadeGarbage) October 7, 2019
完ぺきではないけど大分いいですね。オリジナルの金魚認識モデル生成ができました!
この金魚認識でなのをするかはまた違うお話。
是非またいらしてください。この道へ
246画像(2019/10/16追記)
もう少し我が家の金魚ちゃんたちの写真を増やして、さらに学習時の検証回数”valid_times”を1から3に増やしました。
学習時の検証回数を1から3に増やしたら認識精度はものすごく上がった!
これならイケる!! pic.twitter.com/SlsEsVu4BN— HomeMadeGarbage (@H0meMadeGarbage) October 16, 2019
ほぼ完ぺきに認識しだした。。。やったー!
参考
追記
2020/1/16
Yolo-digit-detectorやMaix Toolboxに更新があるとのことでここで紹介した手法だと現在(2020年1月)エラーがでるようです。
紅樹タカオさん が解決してくれていますので是非ご参照ください。