Acerca de la conversión del modelo SavedModel de Tesorflow en un modelo tflite

Crear un modelo de Tensorflow

Debido a las limitaciones del dispositivo, la plataforma Android no puede entrenar el modelo por sí misma, por lo que es necesario utilizar un modelo existente.
En este artículo, presentaremos cómo convertir el modelo Tensorflow en un modelo tflite, que puede ser utilizado por dispositivos Android.

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")

Aplique el modelo tensorflow en Python y pruébelo

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

Utilice tflite_convert para exportar el modelo tensorflow a tflite

Ejecutar en consola:

tflite_convert __saved_model_dir=forAndroid __output_file=model.tflite

Se produjo un error durante la ejecución. El error es el siguiente:

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'

Reconstruya Tensorflow de acuerdo con el mensaje de error.
La solución oficial proporcionada por Tensorflow es usar bazel para compilar tflite_convert.
El formulario es:
bazel run tflite_convert save_model_dir=directory__output_file=target.tflite.
Debido a que el costo de instalar bazel en Windows 10 es demasiado alto
, La idea de solución se ajusta.

la solución

Entonces recurrí a ejecutar código para implementar la conversión, con la esperanza de obtener más información.
Edite el siguiente código:

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)
Problemas que surgen

Se produjo un error al ejecutar el programa de conversión. El contenido del error es el siguiente:
Registro de errores de mensajes rápidos

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.
......

El registro contiene una gran cantidad de información de error. Agregue el siguiente contenido:

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)

Ignore las advertencias básicas y descubra que el archivo tflite se ha generado correctamente.

Supongo que te gusta

Origin blog.csdn.net/userhu2012/article/details/121530461
Recomendado
Clasificación