見出し画像

TensorFlow Lite入門 / Pythonによる実行

TensorFlow LiteモデルをPythonで実行する方法を説明します。
(情報源)

1. TensorFlow Liteインタープリタ専用のパッケージ

TensorFlowパッケージを完全インストールするより、「TensorFlow Liteインタープリタ」のみをインストールした方がお手軽です。
インタープリタ専用のパッケージは、TensorFlowパッケージの一部で、TensorFlow Liteで推論を実行するために必要な「Interpreterクラス」のみが含まれています。

2. TensorFlow Liteインタープリタのみのインストール

以下からシステムと適合するPythonホイールをダウンロードし、pipでインストールしてください。

◎ARM 32
・Python 3.5: tflite_runtime-1.14.0-cp35-cp35m-linux_armv7l.whl
・Python 3.6: N/A
・Python 3.7: tflite_runtime-1.14.0-cp37-cp37m-linux_armv7l.whl

◎ARM 64
・Python 3.5: tflite_runtime-1.14.0-cp35-cp35m-linux_aarch64.whl
・Python 3.6: N/A
・Python 3.7: tflite_runtime-1.14.0-cp37-cp37m-linux_aarch64.whl

◎x86-64
・Python 3.5: tflite_runtime-1.14.0-cp35-cp35m-linux_x86_64.whl
・Python 3.6: tflite_runtime-1.14.0-cp36-cp36m-linux_x86_64.whl
・Python 3.7: tflite_runtime-1.14.0-cp37-cp37m-linux_x86_64.whl

Ubuntu(x86-64)のPython 3.6にインストールするには、「tflite_runtime-1.14.0-cp36-cp36m-linux_x86_64.whl」をダウンロードして、次のコマンドを入力します。

$ pip3 install tflite_runtime-1.14.0-cp36-cp36m-linux_x86_64.whl

3. 動作確認

試しに、TensorFlow Liteの画像分類のデモを実行してみます。

TensorFlow Lite Python image classification demo

(1)以下のコマンドで、画像とTensorFlow Liteモデルとラベルをダウンロード。

$ curl https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/lite/examples/label_image/testdata/grace_hopper.bmp > /tmp/grace_hopper.bmp
$ curl https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz | tar xzv -C /tmp
$ curl https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_1.0_224_frozen.tgz  | tar xzv -C /tmp  mobilenet_v1_1.0_224/labels.txt
$ mv /tmp/mobilenet_v1_1.0_224/labels.txt /tmp/

(2)「label_image.py」のインポートを以下のように変更。

from tensorflow.lite.python.interpreter import Interpreter

from tflite_runtime.interpreter import Interpreter

インタープリタ専用のパッケージは、インポート名が「tensorflow.lite.python」ではなく「tflite_runtime」になっているため、変更しています。

(3)「label_image.py」を実行。
引数で、TensorFlow Liteモデルとラベルと推論する画像ファイルを指定します。

$ python3 label_image.py \
    --model_file /tmp/mobilenet_v1_1.0_224.tflite \
    --label_file /tmp/labels.txt \
    --image /tmp/grace_hopper.bmp

成功すると、次のように推論結果が表示されます。

0.792127: 653:military uniform
0.084584: 907:Windsor tie
0.021034: 458:bow tie, bow-tie, bowtie
0.009951: 668:mortarboard
0.007782: 514:cornet, horn, trumpet, trump

4. label_image.pyの中身

label_image.pyの中身は次の通りです。

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import numpy as np

from PIL import Image

from tensorflow.lite.python.interpreter import Interpreter


# ラベルの読み込み
def load_labels(filename):
    with open(filename, 'r') as f:
        return [line.strip() for line in f.readlines()]

# メインの実行
if __name__ == '__main__':
    # 引数のパース
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        '--image',
        default='/tmp/grace_hopper.bmp',
        help='image to be classified')
    parser.add_argument(
        '-m',
        '--model_file',
        default='/tmp/mobilenet_v1_1.0_224_quant.tflite',
        help='.tflite model to be executed')
    parser.add_argument(
        '-l',
        '--label_file',
        default='/tmp/labels.txt',
        help='name of file containing labels')
    parser.add_argument(
        '--input_mean',
        default=127.5, type=float,
        help='input_mean')
    parser.add_argument(
        '--input_std',
        default=127.5, type=float,
        help='input standard deviation')
    args = parser.parse_args()


    # インタプリタの生成
    interpreter = Interpreter(model_path=args.model_file)
    interpreter.allocate_tensors()

    # 入力情報と出力情報の取得
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()

    # 入力テンソル種別の取得(Floatingモデルかどうか)
    floating_model = input_details[0]['dtype'] == np.float32

    # 幅と高さの取得(NxHxWxC, H:1, W:2)
    height = input_details[0]['shape'][1]
    width = input_details[0]['shape'][2]

    # 入力画像のリサイズ
    img = Image.open(args.image).resize((width, height))

    # 入力データの生成
    input_data = np.expand_dims(img, axis=0)

    # Floatingモデルのデータ変換
    if floating_model:
        input_data = (np.float32(input_data) - args.input_mean) / args.input_std
 
    # 入力をインタプリタに指定
    interpreter.set_tensor(input_details[0]['index'], input_data)

    # 推論の実行
    interpreter.invoke()

    # 出力の取得
    output_data = interpreter.get_tensor(output_details[0]['index'])
    results = np.squeeze(output_data)


    # 出力の上位5件の表示
    top_k = results.argsort()[-5:][::-1]
    labels = load_labels(args.label_file)
    for i in top_k:
        if floating_model:
            print('{:08.6f}: {}'.format(float(results[i]), labels[i]))
        else:
            print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i]))

5. InterpreterのAPIリファレンス

「TensorFlow Lite」のインタープリタのインターフェイスは次の通り。

◎ __init__(model_path=None, model_content=None)
コンストラクタ。
ファイルパスまたはモデルを指定。

◎ allocate_tensors()

◎ get_input_details()
モデル入力の詳細(list)の取得。

◎ get_output_details()
モデルの出力の詳細(list)の取得。

◎ get_tensor(tensor_index)
テンソル(numpy)のコピーの取得。

◎ get_tensor_details()
有効なテンソル詳細(list)の取得。

◎ invoke()
インタープリタを呼び出す。
これを呼び出す前に、必ず入力サイズと入力値を指定。

◎ reset_all_variables()

◎ resize_tensor_input(input_index, tensor_size)
入力テンソルのサイズの指定。

◎ set_tensor(tensor_index, value)
入力テンソルの値の指定。

◎ tensor(tensor_index)
テンソル(numpy)の取得。


この記事が気に入ったらサポートをしてみませんか?