Перенос кода TFLite на TF2

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

TensorFlow Lite (TFLite) — это набор инструментов, который помогает разработчикам выполнять вывод ML на устройстве (мобильном, встроенном устройстве и устройстве IoT). Преобразователь TFLite — это один из таких инструментов, который преобразует существующие модели TF в оптимизированный формат модели TFLite, который можно эффективно запускать на устройстве.

В этом документе вы узнаете, какие изменения вам нужно внести в код преобразования TF в TFLite, а также несколько примеров, которые делают то же самое.

Изменения в вашем коде конвертации TF в TFLite

  • Если вы используете устаревший формат модели TF1 (файл Keras, замороженный GraphDef, контрольные точки, tf.Session и т. д.), обновите его до TF1/TF2 SavedModel и используйте API конвертера TF2 tf.lite.TFLiteConverter.from_saved_model(...) , чтобы преобразовать его в модель TFLite (см. Таблицу 1).

  • Обновите флаги API конвертера (см. Таблицу 2).

  • Удалите устаревшие API, такие как tf.lite.constants . (например: заменить tf.lite.constants.INT8 на tf.int8 )

// Таблица 1 // Обновление API конвертера TFLite Python

API ТФ1 API ТФ2
tf.lite.TFLiteConverter.from_saved_model('saved_model/',..) поддерживается
tf.lite.TFLiteConverter.from_keras_model_file('model.h5',..) удалено (обновление до формата SavedModel)
tf.lite.TFLiteConverter.from_frozen_graph('model.pb',..) удалено (обновление до формата SavedModel)
tf.lite.TFLiteConverter.from_session(sess,...) удалено (обновление до формата SavedModel)

// Таблица 2 // Обновление флагов API конвертера TFLite Python

API ТФ1 API ТФ2
allow_custom_ops
optimizations
representative_dataset
target_spec
inference_input_type
inference_output_type
experimental_new_converter
experimental_new_quantizer
поддерживается







input_tensors
output_tensors
input_arrays_with_shape
output_arrays
experimental_debug_info_func
удалено (неподдерживаемые аргументы API преобразователя)




change_concat_input_ranges
default_ranges_stats
get_input_arrays()
inference_type
quantized_input_stats
reorder_across_fake_quant
удалено (неподдерживаемые рабочие процессы квантования)





conversion_summary_dir
dump_graphviz_dir
dump_graphviz_video
удалено (вместо этого визуализируйте модели с помощью Netron или visualize.py )


output_format
drop_control_dependency
удалено (неподдерживаемые функции в TF2)

Примеры

Теперь вы познакомитесь с некоторыми примерами преобразования устаревших моделей TF1 в модели TF1/TF2 SavedModels, а затем сконвертируете их в модели TF2 TFLite.

Настраивать

Начните с необходимого импорта 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

Создайте все необходимые форматы моделей TF1.

# 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. Преобразуйте SavedModel TF1 в модель TFLite.

До: Преобразование с помощью TF1

Это типичный код для преобразования TFlite в стиле 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.

После: Преобразование с помощью TF2

Напрямую конвертируйте SavedModel TF1 в модель TFLite, установив меньшие флаги преобразователя версии 2.

# 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. Преобразуйте файл модели TF1 Keras в модель TFLite.

До: Преобразование с помощью TF1

Это типичный код для преобразования TFlite в стиле 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.

После: Преобразование с помощью TF2

Сначала преобразуйте файл модели Keras TF1 в SavedModel TF2, а затем преобразуйте его в модель TFLite с установленными флагами конвертера меньшего размера v2.

# 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. Преобразование замороженного GraphDef TF1 в модель TFLite.

До: Преобразование с помощью TF1

Это типичный код для преобразования TFlite в стиле 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.

После: Преобразование с помощью TF2

Сначала преобразуйте замороженный GraphDef TF1 в SavedModel TF1, а затем преобразуйте его в модель TFLite с установленными флагами преобразования меньшего размера v2.

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

дальнейшее чтение

  • Обратитесь к руководству TFLite , чтобы узнать больше о рабочих процессах и новейших функциях.
  • Если вы используете код TF1 или устаревшие форматы моделей TF1 (файлы Keras .h5 , замороженный GraphDef .pb и т. д.), обновите свой код и перенесите свои модели в формат TF2 SavedModel .