Escribí un artículo antes para convertir el modelo mnn
Pero en lugar de empezar desde el principio, es un modelo que se usa directamente, este artículo quiere hacerlo directamente desde el principio hasta el final.
El código para entrenar el modelo es el siguiente:
Nota: Este código debe ser tf2.3 y superior para ejecutarse, los siguientes códigos se ejecutan en tf2.3
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
batch_size = 2
img_height = 180
img_width = 180
num_classes = 5
epochs = 1
data_dir='flower_photos'
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
data_augmentation = keras.Sequential(
[
layers.experimental.preprocessing.RandomFlip("horizontal",
input_shape=(img_height,
img_width,
3)),
layers.experimental.preprocessing.RandomRotation(0.1),
layers.experimental.preprocessing.RandomZoom(0.1),
]
)
model = Sequential([
data_augmentation,
layers.experimental.preprocessing.Rescaling(1./255),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
print(model.summary())
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
#tf.saved_model.save(model,'saved_model')
model.save('flow.h5')
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
open("flow.tflite", "wb").write(tflite_model)
El código de entrenamiento y los datos son un caso del sitio web oficial de TF.
Después de que el entrenamiento sea exitoso, se guardará un archivo h5 y tflite
Podemos probar el modelo h5:
import tensorflow as tf
import cv2
import numpy as np
image = cv2.imread('397.jpg')
image=cv2.resize(image,(180,180))
image=image[np.newaxis,:,:,:]
print(image.shape)
loaded_model = tf.keras.models.load_model('flow.h5')
print(loaded_model.predict(image))
resultado de la operación:
[[ 0.18912865 1.8175818 -0.41742945 -1.3345877 -0.3854989 ]]
Eche un vistazo a los resultados de la predicción de tflite:
import tensorflow as tf
import cv2
import numpy as np
image = cv2.imread('397.jpg')
image=cv2.resize(image,(180,180))
image=image[np.newaxis,:,:,:].astype(np.float32)
print(image.shape)
interpreter = tf.lite.Interpreter(model_path='flow.tflite')
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
interpreter.set_tensor(input_details[0]['index'],image)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)
resultado de la operación:
(1, 180, 180, 3)
[[ 0.18912843 1.8175817 -0.41742924 -1.3345877 -0.385499 ]]
Los resultados de los dos son básicamente los mismos
Hasta ahora demostró que el modelo tflite es normal.
¿Por qué usar tflite directamente aquí, porque tf ahora puede usar tf.lite.TFLiteConverter.from_keras_model para transferir directamente el modelo de keras, en lugar de escribir mucho código para convertir el archivo pb, porque h5 no puede transferir directamente mnn o pb? ser transferido, por lo que a menudo usamos h5 para convertir a pb y luego a mnn
Lo siguiente que debe hacerse, por supuesto, es convertir tflite al modelo mnn
mnnconvert -f TFLITE --modelFile flow.tflite --MNNModel model-flow.mnn
Puede obtener el archivo mnn si lo ejecuta correctamente:
Podemos usar la API de Python especial de mnn para llamar directamente. Por el momento, este artículo no usará c ++ para llamar a los archivos del modelo mnn.
import MNN
import cv2
import numpy as np
interpreter = MNN.Interpreter("flows/model-flow.mnn")
session = interpreter.createSession()
input_tensor = interpreter.getSessionInput(session)
image = cv2.imread('397.jpg')
image=cv2.resize(image,(180,180)).astype(np.float32)
#print(type(image[0][9][0]))
tmp_input = MNN.Tensor((1,180, 180,3), MNN.Halide_Type_Float,image,MNN.Tensor_DimensionType_Tensorflow)
#print(tmp_input)
input_tensor.copyFrom(tmp_input)
interpreter.runSession(session)
#print(2)
output_tensor = interpreter.getSessionOutput(session)
output_data=np.array(output_tensor.getData())
print(output_data)
La operación exitosa también puede obtener los resultados del modelo keras y el modelo tflite anteriores
[[ 2.0448089 2.6208436 -0.15651277 -2.080144 0.5771749 ]]
Los datos del resultado son diferentes porque la imagen probada por mnn no es una imagen
Finalmente, adjunte la imagen de la imagen de predicción: