機械学習

【1分でわかる】初心者でも理解できるTensorflowLiteの内容と実装

TensorflowLiteを聞いたことがありますか?

Tensorflowは聞いたことがあるけど、その軽量版なの?

聞いたこともないけど、いったい何ができるの?

という方向けに、何ができるかを見ていきましょう。

TensorflowLiteとは

TensorFlowLiteとは、その名からわかるようにGoogleが開発したオープンソースのディープラーニングライブラリ、TensorFlowの軽量版です。このフレームワークは、モバイルデバイスや組み込みデバイスでの機械学習推論を可能にすることを目指しています。

TensorFlowと、TensorFlowを簡単に扱えるKerasに関しては別記事で詳しく書いていますのでそちらを参考にしてください。今回の実装でもKerasで作成したモデルをTensorflowLite用に変換する方法を説明していますが、kerasについては簡単な説明しか記載していないので、以下の記事で詳細を確認してください。

【1分でわかる】初心者でも理解できる!Tensorflow / keras入門ニューラルネットワークモデルを始めようとしている方が、まずは簡単にしっかり成形されたモデルを作成できるように、Tensorflowとkerasを使ってモデルの作成を解説していきます。実際にコードを示しながら進めているので、一緒に手を動かしながら学べます!...

TensorflowLiteの特徴

TensorflowLiteの主な特徴は

  • 軽量性: TensorFlow Liteは、元のTensorFlowライブラリよりも大幅に小さいサイズで設計されています。そのため様々なデバイス上での実行が容易になります。主にモバイルやラズベリーパイで動作させるときに非常に役に立ちます。
  • 速度: モバイルデバイス上での高速な推論を可能にします。
  • 柔軟性: 軽量性のところでも書いた通り、モバイルやラズベリーパイでの動作も可能です。
  • 簡単な統合: TensorFlow Liteは、AndroidやiOSなどのプラットフォームに簡単に統合できます。また、TensorFlowからTensorFlow Liteへのモデル変換も容易です。

となっています。実際にTensorflowLiteに変換して推論してみるとその様子がわかると思うので、以下で実装方法を説明します。

実際に使用してみる

では実際にTensorflow、今回はkerasで作成したモデルをTensorflowLite用に変換して推論してみましょう。

fashion-mnistとは

fashion-mnistは上記のよう衣料品の画像のデータセットです。28x28のデータサイズで10種類のカテゴリーで作成されており、kerasの学習には最適なデータセットです。

kerasモデルの作成

まずは変換元となるモデルをkerasで作成します。導入部分にも書きましたが、詳しい説明は別記事を参照してください。コードは全く同じものを使用しています。以下、モデル作成までのコードです。このコードでfasion-mnist用の判別モデルを作成できます。時間のない方は次の「kerasモデルの保存」の項目まで飛ばしてください

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout

(x, y), (test_x, test_y) = tf.keras.datasets.fashion_mnist.load_data()
train_x, val_x, train_y, val_y = train_test_split(x, y, train_size=0.8)
target_name = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

input_shape = (train_x.shape[1], train_x.shape[2], 1)

model = Sequential(name='test_model')
model.add(Flatten(name='Flatten', input_shape=input_shape))
model.add(Dense(128, activation='relu', name='Dense'))
model.add(Dropout(0.2, name='Dropout'))
model.add(Dense(10, activation='softmax', name='Output'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

history = model.fit(train_x, train_y, epochs=20, validation_data=(val_x, val_y))

コードの内容を簡単に解説しておきます。

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout

必要なライブラリをインポートしています。TensorflowLiteも「Tensorflow」の中に入っていますので、「Tensorflow」を読み込めば特に別のライブラリを読み込む必要はありません。

(x, y), (test_x, test_y) = tf.keras.datasets.fashion_mnist.load_data()
train_x, val_x, train_y, val_y = train_test_split(x, y, train_size=0.8)
target_name = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

fashion-mnistのデータを読み込んで、トレーニングデータを一部検証用データに分けたのち、fashion-mnistには分類名がないため、分類名を登録しています。

input_shape = (train_x.shape[1], train_x.shape[2], 1)

model = Sequential(name='test_model')
model.add(Flatten(name='Flatten', input_shape=input_shape))
model.add(Dense(128, activation='relu', name='Dense'))
model.add(Dropout(0.2, name='Dropout'))
model.add(Dense(10, activation='softmax', name='Output'))

modelをkerasのSequentialモデルで作成しています。理解のしやすさを重視したため、中間層が1層だけ、Dropoutをしただけの最低限のモデルです。

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

history = model.fit(train_x, train_y, epochs=20, validation_data=(val_x, val_y))

modelをコンパイルしたのち、学習をしています。TensorflowLiteに変換するモデルは、この学習済みのものを用意します。

ここまででkerasで簡単なmodelが作成できました。実際にTensorflowLiteを使用する際にもこのような形で学習済みモデルを用意してください。

kerasモデルの保存

ここから実際に作成済みモデルをTensorflowLiteに変換していきます。ここからは実行内容ごとにコードを確認していきましょう。

model.save('saved_model')

TensorflowLiteは保存済みモデルから変換するので、まずはmodelを保存します

tfliteモデルへの変換

input = "saved_model"
output = "./models/output.tflite"

保存済みモデルを読み込んで、TensorflowLiteモデル「.tflite」ファイルとして出力します。「input」に先ほど保存したモデル、「output」に「.tflite」出力先フォルダを指定します。ここで保存先フォルダが作成されていない場合は作成しておいてください。

conv = tf.lite.TFLiteConverter.from_saved_model(input)
tflite_model = conv.convert()
with open(output, 'wb') as o:
    o.write(tflite_model)

tf.lite.TFLiteConverter.from_saved_model()」でモデルを読み込み、「conv.convert()」でモデルを変換します。その後、変換したモデルを「open」で開いたファイルに書き込みます。

tfliteモデルの読み込みと推論

interpreter = tf.lite.Interpreter(model_path="./models/output.tflite")
interpreter.allocate_tensors()

tf.lite.Interpreter()」でtfliteモデルを読み込みます。その後「allocate_tensors()」でメモリを確保してやります。この作業は必ず実行が必要です。

input_details = interpreter.get_input_details()

ここはモデルの推論には直接必要ありませんが、読み込んだモデルに関してinputの詳細を確認します。ここで「shape」を確認し、推論時に流し込むデータの形式を確認してください。この形になっていないとエラーが発生します。

output_details = interpreter.get_output_details()

念のため、output側の情報の確認の仕方と結果を載せておきます。

input_data = test_x[0].reshape(1, 28, 28, 1)
input_data = np.array(input_data, dtype=np.float32)

上記で確認したinputのshapeを参考に、入力データの形を変形しました。今回は推論用に冒頭で準備したtest_xの1つ目のデータを使用します。

推論に要するデータはfloat32である必要があるので、shapeを変更したのちfloat32に変換します。

推論に要するデータはfloat32である必要があります

 

interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()

interpreter.set_tensor()にデータをセットします。インデックス数、入力データをセットし、「invoke()」で推論します。

output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

推論結果はinvoke()が返すのではなく、「get_tensor()」で取得します。推論結果は「output_details」の「index」に格納されています。

今回はカテゴリ「9」と推論しているようですね。

plt.title(y[0])
plt.imshow(x[0])

では先ほど推論に使用したデータを確認してみます。カテゴリ「9」のデータを推論用データとして使用していました。正しく推論できていたようです。

まとめ

今回はTensorflowLiteにモデルを変換して推論するまでを見てみました。実際にはモデル作成までをPC側、推論部分をモバイルやラズベリーパイで行う、というパターンが多いと思いますが、実行の方法は同じです。

今回の内容を参考にしていただき、TensorflowLiteを活用していただければと思います。