将 Keras 模型转换为 TensorFlow lite - 如何避免不支持的操作?

Posted

技术标签:

【中文标题】将 Keras 模型转换为 TensorFlow lite - 如何避免不支持的操作?【英文标题】:Converting a Keras model to TensorFlow lite - how to avoid unsupported operations? 【发布时间】:2021-12-21 13:46:11 【问题描述】:

我有基于 MobileNetV2 的模型,它使用 TimeDistributed 层。我想将该模型转换为 TensorFlow Lite 模型以便在智能手机上运行它,但存在未定义的操作。

代码如下:

import tensorflow as tf

IMAGE_SHAPE = (224, 224, 3)

mobilenet_model = tf.keras.applications.MobileNetV2(input_shape=IMAGE_SHAPE,
                                               include_top=False,
                                               pooling='avg',
                                               weights='imagenet')

inputs = tf.keras.Input(shape=(5,) + IMAGE_SHAPE)
x = tf.keras.applications.mobilenet_v2.preprocess_input(inputs)
outputs = tf.keras.layers.TimeDistributed(mobilenet_model)(x)
model = tf.keras.Model(inputs, outputs)
model.compile()
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tfmodel = converter.convert() # fails

这是错误信息:

error: failed while converting: 'main': 
Some ops are not supported by the native TFLite runtime, you can enable TF kernels fallback using TF Select. See instructions: https://www.tensorflow.org/lite/guide/ops_select 
TF Select ops: Mul
Details:
    tf.Mul(tensor<?x5x224x224x3xf32>, tensor<f32>) -> (tensor<?x5x224x224x3xf32>)

该错误是由输入预处理和 TimeDistributed 层之间的交互引起的。如果我禁用输入预处理,则转换成功,但显然如果不重新训练,网络将无法正常工作。也可以转换具有预处理但没有 TimeDistributed 层的模型。是否可以将预处理移至其他位置以避免此错误?

此外,添加选择操作有助于成功转换它,但我不确定如何在运行时启用它们。我正在使用 Mediapipe 框架来构建一个 android 应用程序。而且我认为 Mediapipe 不支持链接到额外的操作。

【问题讨论】:

作为参考,我通过将tf.keras.applications.mobilenet_v2.preprocess_input 替换为我自己的自定义层来解决这个问题,该层执行相同的预处理并返回正确的输出形状。 【参考方案1】:

查看documentation 了解如何转换它并在 android 中使用它。也许你会成功。如果不回来再ping我一次。

你可以试一试:

converter.target_spec.supported_ops = [
  tf.lite.OpsSet.TFLITE_BUILTINS, # enable TensorFlow Lite ops.
  tf.lite.OpsSet.SELECT_TF_OPS # enable TensorFlow ops.
]

如果你的 tensorflow 版本是 2.6.0 或 2.6.1

检查允许列表操作员here

最好的

【讨论】:

【参考方案2】:

试试这个转换模型。

converter = TFLiteConverter.from_saved_model(model_dir)
converter.experimental_new_converter = False
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS]
converter.allow_custom_ops=True
tflite_model = converter.convert()

【讨论】:

不要使用experimental_new_converter = False。这会触发已弃用且不支持许多团队新功能的旧代码路径。另外,运行时也会出现类似的问题,并不能解决问题所问的问题。

以上是关于将 Keras 模型转换为 TensorFlow lite - 如何避免不支持的操作?的主要内容,如果未能解决你的问题,请参考以下文章

python 将模型从keras转换为tensorflow

tensorflow 为 tensorflowjs 转换 keras 模型

将 Keras 模型转换为 TensorFlow lite - 如何避免不支持的操作?

将 Convnet.js 神经网络模型转换为 Keras Tensorflow

将存储在 tfrecord 格式的数据转换为 Tensorflow 中 lstm Keras 模型的输入,并用该数据拟合模型

如何将保存的模型转换或加载到 TensorFlow 或 Keras?