Tesorflow の SavedModel モデルの tflite モデルへの変換について

Tensorflow モデルを作成する

デバイスの制限により、Android プラットフォームではモデル自体をトレーニングできないため、既存のモデルを使用する必要があります。
この記事では、Tensorflow モデルを Android デバイスで使用できる tflite モデルに変換する方法を紹介します。

import tensorflow as tf
import numpy as np                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import Model
import matplotlib.pyplot as plt

# 读取训练用的输入特征和标签
fashion = tf.keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion.load_data()

x_train =x_train.reshape(x_train.shape[0],28,28,1).astype("float32")
x_test  = x_test.reshape(x_test.shape[0],28,28,1).astype("float32")

# 输入特征归一化,减小计算量,将图片默认为0~255之间的数字,方便神经网络吸收
x_train, x_test = x_train/255.0, x_test/255.0
class_name = ["T恤","裤子","帽头衫","连衣裙","外套","凉鞋","衬衫","运动鞋","包","靴子"]

class FashionModel_CNN(tf.keras.Model):
    """
    定义CNN网络结构
    """
    def __init__(self):
        super().__init__()
        self.conv1 = tf.keras.layers.Conv2D(filters=32, kernel_size=[5,5], padding='valid',input_shape=(28,28,1),activation=tf.nn.relu)
        self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2,2],strides = 2)
        self.conv2 = tf.keras.layers.Conv2D(filters=64,kernel_size=[5,5],padding="same",activation = tf.nn.relu)
        self.pool2 = tf.keras.layers.MaxPool2D(pool_size = [2,2],strides = 2)
        self.flatten = Flatten() #tf.keras.layers.Reshape(target_shape=(28*28*64,))
        self.dense1 = tf.keras.layers.Dense(units = 128,activation = tf.nn.relu)
        self.dense2 = tf.keras.layers.Dense(units=10,activation = "softmax")
    
    def call(self,inputs):
        x = self.conv1(inputs)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flatten(x)
        x = self.dense1(x)
        x = self.dense2(x)
        output = tf.nn.softmax(x)
        return output
        
   
def generate_nn(x_train,y_train,x_test,y_test):
    
    # 声明神经网络对象
    model = FashionModel_CNN()
    
    # 配置训练方法(优化器,损失函数,评测指标)
    model.compile(optimizer=tf.keras.optimizers.Adam(),
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
                  metrics=[tf.keras.metrics.sparse_categorical_accuracy])
    
    # 执行训练过程
    model.fit(x_train, y_train,
              batch_size=32, epochs=10,
              validation_data=(x_test, y_test),
              validation_freq=1)
    
    # 打印网络结构和参数
    model.summary()
    return model

model = generate_nn(x_train,y_train,x_test,y_test)
tf.saved_model.save(model, "./forAndroid")

Python で tensorflow モデルを適用してテストする

import tensorflow as tf
import numpy as np                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import Model

from tensorflow.python.keras.preprocessing.image import load_img
import matplotlib.pyplot as plt
#加载从指定的目录中加载模型 
model = tf.saved_model.load("./forAndroid")
# 读取训练用的输入特征和标签
fashion = tf.keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion.load_data()

x_train = x_train.reshape(x_train.shape[0],28,28,1).astype("float32")
x_test  = x_test.reshape(x_test.shape[0],28,28,1).astype("float32")

# 输入特征归一化,减小计算量,将图片默认为0~255之间的数字,方便神经网络吸收
x_train, x_test = x_train/255.0, x_test/255.0
class_name = ["T恤","裤子","帽头衫","连衣裙","外套","凉鞋","衬衫","运动鞋","包","靴子"]
#测试数据集的路径
path = "./test_data/exam_fashion/exam_fashion/"
images = ["%d.jpeg"%i for i in range(0,10)]
matrix = np.full(784,255.0).reshape(28,28)
images_data=[]

for imgfile in images:
    img_name = "%s%s"%(path,imgfile)
    print(img_name)
    img = tf.keras.preprocessing.image.load_img(img_name,color_mode="grayscale",target_size=(28,28))
    
    img_data = tf.keras.preprocessing.image.img_to_array(img)
    img_data = matrix-img_data.reshape(28,28) 
    #将numpy数组的数据从float64转换成float32
    images_data.append(img_data.astype('float32'))
#测试样本
images_data = np.array(images_data).reshape(10,28,28,1)
print(x_test.dtype,images_data.dtype)
y_pred = model(images_data)
index_list = np.argmax(y_pred,axis=1)
img_id = 0
index = 1

for i in index_list:
    img_id +=1
    print(index,i,class_name[i])
    index = index+1

tflite_convert を使用して tensorflow モデルを tflite にエクスポートします

コンソールで実行します。

tflite_convert __saved_model_dir=forAndroid __output_file=model.tflite

実行中にエラーが発生しました。エラーは次のとおりです。

2021-11-25 09:19:56.975579: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_UNKNOWN: unknown error
2021-11-25 09:19:56.979582: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: DESKTOP-4CLUK38
2021-11-25 09:19:56.979752: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: DESKTOP-4CLUK38
2021-11-25 09:19:56.991993: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Traceback (most recent call last):
  File "d:\anaconda3\envs\tensorflow\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "d:\anaconda3\envs\tensorflow\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "D:\anaconda3\envs\tensorflow\Scripts\tflite_convert.exe\__main__.py", line 7, in <module>
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\lite\python\tflite_convert.py", line 697, in main
    app.run(main=run_main, argv=sys.argv[:1])
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\absl\app.py", line 303, in run
    _run_main(main, args)
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\absl\app.py", line 251, in _run_main
    sys.exit(main(argv))
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\lite\python\tflite_convert.py", line 680, in run_main
    _convert_tf2_model(tflite_flags)
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\lite\python\tflite_convert.py", line 281, in _convert_tf2_model
    converter = lite.TFLiteConverterV2.from_saved_model(
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\lite\python\lite.py", line 1348, in from_saved_model
    saved_model = _load(saved_model_dir, tags)
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\saved_model\load.py", line 864, in load
    result = load_internal(export_dir, tags, options)["root"]
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\saved_model\load.py", line 902, in load_internal
    loader = loader_cls(object_graph_proto, saved_model_proto, export_dir,
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\saved_model\load.py", line 162, in __init__
    self._load_all()
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\saved_model\load.py", line 259, in _load_all
    self._load_nodes()
  File "d:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\saved_model\load.py", line 448, in _load_nodes
    slot_variable = optimizer_object.add_slot(
AttributeError: '_UserObject' object has no attribute 'add_slot'

エラー メッセージに従って Tensorflow を再構築します。Tensorflow
が提供する公式の解決策は、bazel を使用して tflite_convert をコンパイルすることです。
形式は次のとおりです:
bazel run tflite_convert Saved_model_dir=directory__output_file=target.tflite.
Windows 10 に bazel をインストールするコストは高すぎるため
、解決策のアイデアが調整されます。

ソリューション

そこで、より詳しい情報を得るために、コードを実行して変換を実装することにしました。
次のコードを編集します。

import tensorflow as tf
#指定保存模型的目录
saved_model_dir = "forAndroid"
# 转换模型
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
#转换模型
tflite_model = converter.convert()
# 将转换的模型保持到指定的文件model.tflite
with open('model.tflite', 'wb') as f:
  f.write(tflite_model)
発生する問題

変換プログラム実行時にエラーが発生しました。エラー内容は以下のとおりです。
プロンプトメッセージ エラーログ

2021-11-25 09:28:46.532142: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_UNKNOWN: unknown error
2021-11-25 09:28:46.535042: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: DESKTOP-4CLUK38
2021-11-25 09:28:46.535137: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: DESKTOP-4CLUK38
2021-11-25 09:28:46.535300: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
......

ログには大量のエラー情報が含まれています。次の内容を追加します。

import tensorflow as tf
import os
#指定日志的级别,设置为错误和警告信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#指定保存模型的目录
saved_model_dir = "forAndroid"
# 转换模型
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
#转换模型
tflite_model = converter.convert()
# 将转换的模型保持到指定的文件model.tflite
with open('model.tflite', 'wb') as f:
  f.write(tflite_model)

基本的な警告を無視すると、tflite ファイルが正常に生成されたことがわかります。

おすすめ

転載: blog.csdn.net/userhu2012/article/details/121530461