ML Community Day è il 9 novembre! Unisciti a noi per gli aggiornamenti da tensorflow, JAX, e più Per saperne di più

Migrazione del codice TFLite su TF2

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza la fonte su GitHub Scarica il taccuino

Tensorflow Lite (TFLite) è un insieme di strumenti che aiuta gli sviluppatori correre ML inferenza on-device (, embedded, e dispositivi mobili) dell'Internet degli oggetti. Il convertitore TFLite è un tale strumento che converte exisiting modelli TF in un formato ottimizzato modello TFLite che può essere eseguito in modo efficiente sul dispositivo.

In questo documento imparerai quali modifiche devi apportare al tuo codice di conversione da TF a TFLite, seguito da alcuni esempi che fanno lo stesso.

Modifiche al codice di conversione da TF a TFLite

  • Se si sta utilizzando un formato legacy modello di TF1 (file Keras, GraphDef congelati, posti di blocco, tf.Session, ecc), aggiornarlo a TF1 / TF2 SavedModel e utilizzare l'API convertitore TF2 tf.lite.TFLiteConverter.from_saved_model(...) per convertirlo in un modello TFLite (fare riferimento alla Tabella 1).

  • Aggiorna i flag dell'API del convertitore (fare riferimento alla Tabella 2).

  • Rimuovere le API legacy come tf.lite.constants . (es: sostituire tf.lite.constants.INT8 con tf.int8 )

// Tabella 1 // Aggiornamento API TFLite Python Converter

API TF1 API TF2
tf.lite.TFLiteConverter.from_saved_model('saved_model/',..) supportato
tf.lite.TFLiteConverter.from_keras_model_file('model.h5',..) rimosso (aggiorna al formato SavedModel)
tf.lite.TFLiteConverter.from_frozen_graph('model.pb',..) rimosso (aggiorna al formato SavedModel)
tf.lite.TFLiteConverter.from_session(sess,...) rimosso (aggiorna al formato SavedModel)

// Tabella 2 // Aggiornamento flag API TFLite Python Converter

API TF1 API TF2
allow_custom_ops
optimizations
representative_dataset
target_spec
inference_input_type
inference_output_type
experimental_new_converter
experimental_new_quantizer
supportato







input_tensors
output_tensors
input_arrays_with_shape
output_arrays
experimental_debug_info_func
rimosso (argomenti API del convertitore non supportati)




change_concat_input_ranges
default_ranges_stats
get_input_arrays()
inference_type
quantized_input_stats
reorder_across_fake_quant
rimosso (flussi di lavoro di quantizzazione non supportati)





conversion_summary_dir
dump_graphviz_dir
dump_graphviz_video
rimosso (invece, visualizzare modelli utilizzando Netron o visualize.py )


output_format
drop_control_dependency
rimosso (funzionalità non supportate in TF2)

Esempi

Verranno ora illustrati alcuni esempi per convertire i modelli TF1 legacy in modelli salvati TF1/TF2 e quindi convertirli in modelli TF2 TFLite.

Impostare

Inizia con le importazioni TensorFlow necessarie.

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

Crea tutti i formati del modello TF1 necessari.

# 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. Converti un modello salvato TF1 in un modello TFLite

Prima: conversione con TF1

Questo è il codice tipico per la conversione TFlite in stile 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.

Dopo: Conversione con TF2

Converti direttamente TF1 SavedModel in un modello TFLite, con un set di flag di conversione v2 più piccoli.

# 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. Converti un file modello TF1 Keras in un modello TFLite

Prima: conversione con TF1

Questo è il codice tipico per la conversione TFlite in stile 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.

Dopo: Conversione con TF2

Innanzitutto, converti il ​​file del modello TF1 Keras in un TF2 SavedModel e poi convertilo in un modello TFLite, con un set di flag di conversione v2 più piccolo.

# 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. Converti un GraphDef congelato TF1 in un modello TFLite

Prima: conversione con TF1

Questo è il codice tipico per la conversione TFlite in stile 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.

Dopo: Conversione con TF2

Innanzitutto, converti il ​​GraphDef congelato TF1 in un TF1 SavedModel e poi convertilo in un modello TFLite, con un set di flag di conversione v2 più piccoli.

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

Ulteriori letture

  • Fare riferimento alla Guida TFLite per conoscere meglio i flussi di lavoro e più recenti funzionalità.
  • Se si sta utilizzando il codice TF1 o legacy formati modello TF1 (Keras .h5 file, congelati GraphDef .pb , ecc), si prega di aggiornare il codice e la migrazione dei modelli per il formato di TF2 SavedModel .