Veja no TensorFlow.org | Executar no Google Colab | Ver fonte no GitHub | Baixar caderno |
O TensorFlow Lite (TFLite) é um conjunto de ferramentas que ajuda os desenvolvedores a executar a inferência de ML no dispositivo (dispositivos móveis, incorporados e IoT). O conversor TFLite é uma dessas ferramentas que converte modelos TF existentes em um formato de modelo TFLite otimizado que pode ser executado com eficiência no dispositivo.
Neste documento, você aprenderá quais alterações você precisa fazer no seu código de conversão de TF para TFLite, seguido por alguns exemplos que fazem o mesmo.
Alterações no seu código de conversão de TF para TFLite
Se você estiver usando um formato de modelo TF1 legado (arquivo Keras, GraphDef congelado, pontos de verificação, tf.Session, etc), atualize-o para TF1/TF2 SavedModel e use a API do conversor TF2
tf.lite.TFLiteConverter.from_saved_model(...)
para convertê-lo em um modelo TFLite (consulte a Tabela 1).Atualize os sinalizadores da API do conversor (consulte a Tabela 2).
Remova as APIs legadas, como
tf.lite.constants
. (por exemplo: Substituatf.lite.constants.INT8
portf.int8
)
// Tabela 1 // Atualização da API do conversor TFLite Python
API TF1 | API do TF2 |
---|---|
tf.lite.TFLiteConverter.from_saved_model('saved_model/',..) | suportado |
tf.lite.TFLiteConverter.from_keras_model_file('model.h5',..) | removido (atualize para o formato SavedModel) |
tf.lite.TFLiteConverter.from_frozen_graph('model.pb',..) | removido (atualize para o formato SavedModel) |
tf.lite.TFLiteConverter.from_session(sess,...) | removido (atualize para o formato SavedModel) |
// Tabela 2 // Atualização dos sinalizadores da API do conversor TFLite Python
API TF1 | API do TF2 |
---|---|
allow_custom_ops optimizations representative_dataset target_spec inference_input_type inference_output_type experimental_new_converter experimental_new_quantizer | suportado |
input_tensors output_tensors input_arrays_with_shape output_arrays experimental_debug_info_func | removido (argumentos da API do conversor não suportados) |
change_concat_input_ranges default_ranges_stats get_input_arrays() inference_type quantized_input_stats reorder_across_fake_quant | removido (fluxos de trabalho de quantização não suportados) |
conversion_summary_dir dump_graphviz_dir dump_graphviz_video | removido (em vez disso, visualize modelos usando Netron ou visualize.py ) |
output_format drop_control_dependency | removido (recursos não suportados no TF2) |
Exemplos
Agora, você passará por alguns exemplos para converter modelos TF1 herdados em SavedModels TF1/TF2 e, em seguida, convertê-los em modelos TF2 TFLite.
Configurar
Comece com as importações necessárias do TensorFlow.
import tensorflow as tf
import tensorflow.compat.v1 as tf1
import numpy as np
import logging
logger = tf.get_logger()
logger.setLevel(logging.ERROR)
import shutil
def remove_dir(path):
try:
shutil.rmtree(path)
except:
pass
Crie todos os formatos de modelo TF1 necessários.
# Create a TF1 SavedModel
SAVED_MODEL_DIR = "tf_saved_model/"
remove_dir(SAVED_MODEL_DIR)
with tf1.Graph().as_default() as g:
with tf1.Session() as sess:
input = tf1.placeholder(tf.float32, shape=(3,), name='input')
output = input + 2
# print("result: ", sess.run(output, {input: [0., 2., 4.]}))
tf1.saved_model.simple_save(
sess, SAVED_MODEL_DIR,
inputs={'input': input},
outputs={'output': output})
print("TF1 SavedModel path: ", SAVED_MODEL_DIR)
# Create a TF1 Keras model
KERAS_MODEL_PATH = 'tf_keras_model.h5'
model = tf1.keras.models.Sequential([
tf1.keras.layers.InputLayer(input_shape=(128, 128, 3,), name='input'),
tf1.keras.layers.Dense(units=16, input_shape=(128, 128, 3,), activation='relu'),
tf1.keras.layers.Dense(units=1, name='output')
])
model.save(KERAS_MODEL_PATH, save_format='h5')
print("TF1 Keras Model path: ", KERAS_MODEL_PATH)
# Create a TF1 frozen GraphDef model
GRAPH_DEF_MODEL_PATH = tf.keras.utils.get_file(
'mobilenet_v1_0.25_128',
origin='https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_0.25_128_frozen.tgz',
untar=True,
) + '/frozen_graph.pb'
print("TF1 frozen GraphDef path: ", GRAPH_DEF_MODEL_PATH)
TF1 SavedModel path: tf_saved_model/ TF1 Keras Model path: tf_keras_model.h5 Downloading data from https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_0.25_128_frozen.tgz 2621440/2617289 [==============================] - 0s 0us/step 2629632/2617289 [==============================] - 0s 0us/step TF1 frozen GraphDef path: /home/kbuilder/.keras/datasets/mobilenet_v1_0.25_128/frozen_graph.pb
1. Converter um TF1 SavedModel em um modelo TFLite
Antes: Convertendo com TF1
Este é um código típico para conversão TFlite no estilo TF1.
converter = tf1.lite.TFLiteConverter.from_saved_model(
saved_model_dir=SAVED_MODEL_DIR,
input_arrays=['input'],
input_shapes={'input' : [3]}
)
converter.optimizations = {tf.lite.Optimize.DEFAULT}
converter.change_concat_input_ranges = True
tflite_model = converter.convert()
# Ignore warning: "Use '@tf.function' or '@defun' to decorate the function."
2021-09-22 20:02:56.143221: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:56.143267: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:56.143274: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
Depois: Convertendo com TF2
Converta diretamente o TF1 SavedModel para um modelo TFLite, com um conjunto de sinalizadores de conversor v2 menor.
# Convert TF1 SavedModel to a TFLite model.
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir=SAVED_MODEL_DIR)
converter.optimizations = {tf.lite.Optimize.DEFAULT}
tflite_model = converter.convert()
2021-09-22 20:02:56.207882: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:56.207923: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:56.207930: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
2. Converta um arquivo de modelo TF1 Keras em um modelo TFLite
Antes: Convertendo com TF1
Este é um código típico para conversão TFlite no estilo TF1.
converter = tf1.lite.TFLiteConverter.from_keras_model_file(model_file=KERAS_MODEL_PATH)
converter.optimizations = {tf.lite.Optimize.DEFAULT}
converter.change_concat_input_ranges = True
tflite_model = converter.convert()
2021-09-22 20:02:56.608343: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. 2021-09-22 20:02:57.119836: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:57.119881: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:57.119888: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
Depois: Convertendo com TF2
Primeiro, converta o arquivo de modelo TF1 Keras em um TF2 SavedModel e, em seguida, converta-o em um modelo TFLite, com um conjunto de sinalizadores de conversor v2 menor.
# Convert TF1 Keras model file to TF2 SavedModel.
model = tf.keras.models.load_model(KERAS_MODEL_PATH)
model.save(filepath='saved_model_2/')
# Convert TF2 SavedModel to a TFLite model.
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir='saved_model_2/')
tflite_model = converter.convert()
2021-09-22 20:02:57.943564: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:57.943608: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:57.943614: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
3. Converta um GraphDef congelado TF1 em um modelo TFLite
Antes: Convertendo com TF1
Este é um código típico para conversão TFlite no estilo TF1.
converter = tf1.lite.TFLiteConverter.from_frozen_graph(
graph_def_file=GRAPH_DEF_MODEL_PATH,
input_arrays=['input'],
input_shapes={'input' : [1, 128, 128, 3]},
output_arrays=['MobilenetV1/Predictions/Softmax'],
)
converter.optimizations = {tf.lite.Optimize.DEFAULT}
converter.change_concat_input_ranges = True
tflite_model = converter.convert()
2021-09-22 20:02:58.139650: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:58.139707: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:58.139721: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
Depois: Convertendo com TF2
Primeiro, converta o GraphDef congelado do TF1 em um TF1 SavedModel e, em seguida, converta-o em um modelo TFLite, com um conjunto de sinalizadores de conversor v2 menor.
## Convert TF1 frozen Graph to TF1 SavedModel.
# Load the graph as a v1.GraphDef
import pathlib
gdef = tf.compat.v1.GraphDef()
gdef.ParseFromString(pathlib.Path(GRAPH_DEF_MODEL_PATH).read_bytes())
# Convert the GraphDef to a tf.Graph
with tf.Graph().as_default() as g:
tf.graph_util.import_graph_def(gdef, name="")
# Lookup the input and output tensors.
input_tensor = g.get_tensor_by_name('input:0')
output_tensor = g.get_tensor_by_name('MobilenetV1/Predictions/Softmax:0')
# Save the graph as a TF1 Savedmodel
remove_dir('saved_model_3/')
with tf.compat.v1.Session(graph=g) as s:
tf.compat.v1.saved_model.simple_save(
session=s,
export_dir='saved_model_3/',
inputs={'input':input_tensor},
outputs={'output':output_tensor})
# Convert TF1 SavedModel to a TFLite model.
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir='saved_model_3/')
converter.optimizations = {tf.lite.Optimize.DEFAULT}
tflite_model = converter.convert()
2021-09-22 20:02:58.874490: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:351] Ignored output_format. 2021-09-22 20:02:58.874538: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:354] Ignored drop_control_dependency. 2021-09-22 20:02:58.874545: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored change_concat_input_ranges.
Leitura adicional
- Consulte o Guia TFLite para saber mais sobre os fluxos de trabalho e os recursos mais recentes.
- Se você estiver usando código TF1 ou formatos de modelo TF1 legados (arquivos Keras
.h5
, GraphDef.pb
congelado etc.), atualize seu código e migre seus modelos para o formato TF2 SavedModel .