(初めての投稿です)
Kerasを使用して学習済みAIモデルを作成し、GR-PEACH(マイコン)上で推論実行させてみました。
e-AIは組み込みデバイス上でAIを動作可能にするツールである。e-AIソリューションはルネサスエレクトロニクスが提供し、Caffeや PyTorchやKeras、Tensorflow(tf.keras API)といった一般的なフレームワークで生成したモデルを容易にマイコンに実装可能にする。
このe-AIが発表されてから暫く経つが、思ってたより活用例を見かけないのは残念なところだ。
久しぶり(2021.5時点)にサイトを見たらKerasに対応したようなので、今回はKerasでFashion-MNISTの学習済みAIモデルを生成しGR-PEACH上で動作させてみた。
記事を書いた/開発した動機:
・Kerasを使ったe-AIチュートリアルなくない?
・mbed OS対応のe-AIサンプルプログラム公開されてる?
・MNISTあきた。。。Fashion-MNIST面白そう。
※筆者はAIについて素人同然なので、この記事にて生じた損害に関し一切の責任を負いません。
開発環境
- Keras(standalone) v2.2.4
- Tensorflow v1.15.0
- TensorFlow-backend 版 Keras v2.2.4-tf(TensorFlow v2.1.0同梱)
- e2studio v7.6.0 - e2stuio v2021-07
- e-AIトランスレータ v1.4.0 - e-AIトランスレータ v2.0.0
- GR-PEACH
実装手順
- Kerasを用いてFasion-MNISTを学習
- e-AIトランスレータで学習済みモデルをCソースに変換
- Fashion-MNISTデータセットからテスト用ファイルを作成
- GR-PEACH用の推論実行プログラム作成
Kerasとは
Kerasは,Pythonで書かれた,TensorFlowまたはCNTK,Theano上で実行可能な高水準のニューラルネットワークライブラリです. Kerasは,迅速な実験を可能にすることに重点を置いて開発されました. アイデアから結果に到達するまでのリードタイムをできるだけ小さくすることが,良い研究をするための鍵になります.(引用元:https://keras.io/ja/ )
2017年にTensorflowのコアライブラリにおいてKerasをサポートすることが決まったことから、完全にtfに取り込まれてしまった感がある。またTensorflowがv2.xになってから記述のしやすさが評価されているが、これはKerasのおかげと言ってもいいと思う。
Kerasは独立版とTensorflow-backend版がある。どちらを使用してもいいと思うが、以降で紹介するe-AIトランスレータにはバージョンの制約があるので注意したほうが良い。
Fashion-MNISTとは
Fashion-MNISTは有名なMNISTと同じく28×28 グレースケール画像で60,000サンプルの訓練セットと10,000サンプルのテストセットから成るデータセットである。通常のMNISTは手書き数字画像だが、Fashion-MNISTはTシャツやズボン、靴といった画像で構成されている。クラス数は10である。
Fashio-MNISTが開発された理由として、開発者は「普通のMNISTは簡単すぎるし使われすぎるから真面目な研究者はFashion-MNISTを使うべきだ」と言っている。
詳しくはこちら。
(引用元:https://github.com/zalandoresearch/fashion-mnist)
Kerasを用いてFashion-MNISTを学習
環境構築
まずは作業環境を構築する必要がある。e-AIトランスレータにはバージョン制約があるので、ユーザーズマニュアル(R20UT4135)に従い構築する。
独立型のKerasを使用したくインストールを進めていたが、v2以降のTensorflowではうまく動作しなかった。最終的に筆者の環境では統合前のTensorflow v1.15.0とKeras v2.2.4を使用することでうまく動作した。Anacondaは未使用。
Python関連の環境構築は非常に複雑で、投げ出したくなる作業であると思う。今回はe-AIトランスレータのインストールで構築したTensorflow(Keras)環境を使用する。インストール手順はe-AIトランスレータ ユーザーズマニュアル(R20UT4135)の2章を参照し、順番に行って下さい。
学習環境もe-AIトランスレータもだが、うまく動作しないとエラーが出るのでググれば解決策を得ることができる(時間は犠牲になるが)。
モデル構造
今回は以下の構造/層で構築した。主に畳み込み層を用いた構成である。
入力層(28*28) → 畳み込み層+Relu → 畳み込み層+Relu → プーリング層 → 畳み込み層+Relu → 全結合層 → 全結合層 → 出力層(10)
※e-AIトランスレータは全ての関数をサポートしているわけではないので、ドキュメントを見ながら対応したモジュールを選択肢して書く必要がある。
ソースコード
以下にKerasのソースコードを添付する。
(本ソースコードは下記の文献を参考に作成した。)
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras import backend as K
# kerasのバージョン確認
print(keras.__version__)
# データセット読み込み
fashion_mnist = keras.datasets.fashion_mnist
(train_imgs, train_labels), (test_imgs, test_labels) = fashion_mnist.load_data()
# 前処理
train_imgs = train_imgs.reshape(60000, 28, 28, 1)
test_imgs = test_imgs.reshape(10000, 28, 28, 1)
input_shape = (28, 28, 1)
train_imgs = train_imgs.astype('float32')
test_imgs = test_imgs.astype('float32')
train_imgs /= 255
test_imgs /= 255
train_labels = keras.utils.to_categorical(train_labels, 10)
test_labels = keras.utils.to_categorical(test_labels, 10)
# モデルの構築
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same', input_shape=input_shape))
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D((2,2)))
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
# モデルのコンパイル
model.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
# モデルの訓練
epochs = 10
batch_size = 128
history = model.fit(train_imgs, train_labels, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(test_imgs, test_labels))
# 正解率の評価
scores = model.evaluate(test_imgs, test_labels, verbose=0)
print()
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])
# 結果の出力
model.save('./tf_LearnedModel/fashion_MNIST_model.h5')
また、以下のコマンドをコマンドプロンプトで実行することでe-AIトランスレータのイントール時に構築した環境を使用し、NN学習を実行することができる。
py -3.7 study_mnist.py
学習結果(参考)
参考までに筆者の環境での学習結果(Loss、Accuracy)を示す。
Test loss: 0.32364662846457215
Test accuracy: 0.9237
e-AIトランスレータで学習済みモデルをCソースに変換
出力した学習済みAIモデルのファイル(h5ファイル)の選択及び出力場所の選択、各種設定を行う。
(出力先をする必要があるので事前にターゲットボード用プロジェクトを用意しておいた方が良い。)
Translateボタンをタップすると変換される。
最新バーション(v2.0.0)
旧バージョン(v1.4.0)
Fashion-MNISTデータセットからテスト用ファイルを作成
学習済みAIモデルをCソースに変換できたら推論実行プログラムを作成することになるが、GR-PEACHでカメラ入力は大変そうなので、今回はFashion-MNISTのデータセット(抜粋版)を作成した。
Fashion-MNISTの素の状態はプロテクトされているので、自ら書き出す必要がある。
今回はlabel 0,2,3,5,7,9のデータを適当に1枚づつ引っ張り出し、Cの配列記述に変換した。
作成したファイルを公開しておく。-> ファイルリンク
GR-PEACH用の推論実行プログラム作成
最後にGR-PEACH用の推論実行プログラムを作成する。
筆者はmbed OSに慣れているので、mbedに対応したプログラムを作成した。
特に特殊なことはしていないが、GR-PEACHサイトからe2studio用のサンプルプログラムをダウンロード・インポートしAIの処理を付け加えた。
処理内容はシリアルでHelloし、推論を実行、終了したら結果出力、Lチカの流れである。
ソースコード
以下にGE-PEACH用のコードを添付する。
# include "mbed.h"
# ifdef __cplusplus
extern "C"{
# endif
# include "Typedef.h"
# include "layer_graph.h"
TPrecision* dnn_compute(TPrecision* input_img);
# include "input_data_fashion_mnist.h"
# ifdef __cplusplus
}
# endif
# 宣言
DigitalOut led1(LED1);
TPrecision *prediction;
TPrecision *input_img;
int main() {
printf("fashion-MNIST prediction\r\n");
# label 0 のデータでテスト
printf("No. 0\r\n");
input_img = data_fmnist_0;
t.reset(); // timer reset
t.start(); // timer start
prediction = (TPrecision *) dnn_compute(input_img);
t.stop(); //timer stop
printf("time: %f ms\r\n", t.read_ms()); // time printout
for(int i=0; i<10; i++){
printf("%d : %f\r\n", i, prediction[i]);
}
# label 3 のデータでテスト
printf("No. 3\r\n");
input_img = data_fmnist_3;
t.reset(); // timer reset
t.start(); // timer start
prediction = (TPrecision *) dnn_compute(input_img);
t.stop(); // timer stop
printf("time: %f ms\r\n", t.read_ms()); // time printout
for(int i=0; i<10; i++){
printf("%d : %f\r\n", i, prediction[i]);
}
#推論実行後の処理
wait(0.1);
while(1) {
led1 = !led1;
wait(1);
}
}
作成したらビルドしUSB経由でロードする(数十秒かかるのでひたすら待つ)。
完了したらResetボタンを押し、シリアル出力・LEDを確認する。
実行結果 on teraterm
参考までにResetボタン操作後のシリアル出力を以下に示す。
(筆者はteratermを使用しているが、好きなターミナルソフトを使うと良い。)
思っていたより高速かつ高精度。
ちなみに、Convert OptionはSpeed Priorityに設定しています。RAM Size Priorityの場合、1738msくらいでした。RAMの空き容量と相談して、選択する必要があります。
感想
今回はKerasで生成したAIモデルをGR-PEACH上で実行した。
作業内容は特に難しいものではないが、Kerasとe-AI要求のバージョン違いで非常に多くの時間を使ってしまった。インストールが済んでしまえばあとはそれを使えばいいので、今後はより迅速に開発できると思う。
易実装性なKerasでモデル作成/学習できるようになったので、今後容易にAIを試せるだろう。
参考文献
更新履歴
2021.09.11 e-AIトラインシュレータ V2.0.0用に内容を更新。過去の内容は取り消し線で残しています。