![]() |
![]() |
![]() |
![]() |
TensorFlow Lite (TFLite) 是一組工具,可協助開發人員在裝置端 (行動裝置、嵌入式裝置和 IoT 裝置) 執行 ML 推論。TFLite 轉換器就是其中一種工具,可將現有的 TF 模型轉換為經過最佳化的 TFLite 模型格式,以便在裝置端有效率地執行。
在本文中,您將瞭解您需要對 TF 轉 TFLite 轉換程式碼進行哪些變更,接著會提供幾個執行相同作業的範例。
TF 轉 TFLite 轉換程式碼的變更
如果您使用的是舊版 TF1 模型格式 (例如 Keras 檔案、frozen GraphDef、檢查點、tf.Session),請將其更新為 TF1/TF2 SavedModel,並使用 TF2 轉換器 API
tf.lite.TFLiteConverter.from_saved_model(...)
將其轉換為 TFLite 模型 (請參閱表 1)。更新轉換器 API 旗標 (請參閱表 2)。
移除舊版 API,例如
tf.lite.constants
。(例如:將tf.lite.constants.INT8
替換為tf.int8
)
// 表 1 // TFLite Python 轉換器 API 更新
TF1 API | TF2 API |
---|---|
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 // TFLite Python 轉換器 API 旗標更新
TF1 API | TF2 API |
---|---|
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 SavedModel,然後將其轉換為 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)
1. 將 TF1 SavedModel 轉換為 TFLite 模型
之前:使用 TF1 轉換
這是 TF1 樣式 TFlite 轉換的典型程式碼。
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."
之後:使用 TF2 轉換
使用較小的 v2 轉換器旗標集,將 TF1 SavedModel 直接轉換為 TFLite 模型。
# 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()
2. 將 TF1 Keras 模型檔案轉換為 TFLite 模型
之前:使用 TF1 轉換
這是 TF1 樣式 TFlite 轉換的典型程式碼。
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()
之後:使用 TF2 轉換
首先,將 TF1 Keras 模型檔案轉換為 TF2 SavedModel,然後使用較小的 v2 轉換器旗標集將其轉換為 TFLite 模型。
# 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()
3. 將 TF1 frozen GraphDef 轉換為 TFLite 模型
之前:使用 TF1 轉換
這是 TF1 樣式 TFlite 轉換的典型程式碼。
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()
之後:使用 TF2 轉換
首先,將 TF1 frozen GraphDef 轉換為 TF1 SavedModel,然後使用較小的 v2 轉換器旗標集將其轉換為 TFLite 模型。
## 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="")
# Look up 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()
延伸閱讀
- 請參閱 TFLite 指南,進一步瞭解工作流程和最新功能。
- 如果您使用的是 TF1 程式碼或舊版 TF1 模型格式 (Keras
.h5
檔案、frozen GraphDef.pb
等),請更新您的程式碼,並將您的模型遷移至 TF2 SavedModel 格式。