TFLite 转换器:为 keras 模型实现的 RandomStandardNormal,但不适用于纯 TensorFlow 模型

Posted

技术标签:

【中文标题】TFLite 转换器:为 keras 模型实现的 RandomStandardNormal,但不适用于纯 TensorFlow 模型【英文标题】:TFLite Converter: RandomStandardNormal implemented for keras model, but not for pure TensorFlow model 【发布时间】:2020-01-06 12:45:40 【问题描述】:

任务

我有两个应该是等效的模型。第一个是用 keras 构建的,第二个是用 tensorflow 构建的。两种变分自动编码器都在其模型中使用tf.random.normal 方法。此外,它们产生类似的结果。一切都经过夜间构建 (1.15) 的测试。

当我尝试将它们转换为具有训练后量化的 tensorflow lite 模型时,就会出现混乱。我对两个模型使用相同的命令:

converter = tf.compat.v1.lite.TFLiteConverter... # from respective save file
converter.representative_dataset = representative_dataset_gen
converter.optimizations = [tf.lite.Optimize.DEFAULT]

tflite_model = converter.convert()
open('vae.tflite', 'wb').write(tflite_model)

错误

对于 keras 模型,一切顺利,我最终得到了一个可以工作的 tflite 模型。但是,如果我尝试使用 tensorflow 版本执行此操作,则会遇到一个错误,指出 RandomStandardNormal 未实现:

标准不支持模型中的某些运算符 TensorFlow Lite 运行时。如果这些是原生 TensorFlow 运算符,那么您 可能能够通过传递使用扩展的运行时 --enable_select_tf_ops,或者在调用时设置 target_ops=TFLITE_BUILTINS,SELECT_TF_OPS tf.lite.TFLiteConverter()。否则,如果您有自定义 为他们实现你可以禁用这个错误 --allow_custom_ops,或者在调用 tf.lite.TFLiteConverter() 时设置 allow_custom_ops=True。这是您的内置运算符列表 使用:ADD、EXP、FULLY_CONNECTED、LEAKY_RELU、LOG、MUL。这是一个列表 您将需要自定义实现的运算符: RandomStandardNormal。

问题

这对我来说没有意义,因为显然这已经在使用 keras。 keras 是否知道我必须明确告诉我的 tensorflow 模型的事情?

模型

张量流

fc_layer = tf.compat.v1.layers.dense

# inputs have shape (90,)
x = tf.identity(inputs, name='x')

# encoder
outputs = fc_layer(x, 40, activation=leaky_relu)

self.z_mu = fc_layer(outputs, 10, activation=None)
self.z_sigma = fc_layer(outputs, 10, activation=softplus)

# latent space
eps = tf.random.normal(shape=tf.shape((10,)), mean=0, stddev=1, dtype=tf.float32)
outputs = self.z_mu + eps * self.z_sigma

# decoder
outputs = fc_layer(outputs, 40, activation=leaky_relu)

# prediction
x_decoded = fc_layer(outputs, 90, activation=None)

keras

x = keras.layers.Input(shape=(90,))

h = keras.layers.Dense(40, activation=leakyrelu)(x)

z_mu = keras.layers.Dense(10)(h)
z_sigma = keras.layers.Dense(10, activation=softplus)(h)

eps = tf.random.normal(shape=tf.shape((10,)), mean=0, stddev=1, dtype=tf.float32)
z = z_mu + eps * z_sigma

h_decoded = keras.layers.Dense(40, activation=leakyrelu)(z)
x_decoded = keras.layers.Dense(90)(h_decoded)

train_model = keras.models.Model(x, x_decoded)

【问题讨论】:

我为此打开了一个github issue,它提供了所有测试代码:github.com/tensorflow/tensorflow/issues/32206 【参考方案1】:

!pip install tensorflow==1.15

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_keras_model_file('model.h5') 
converter.allow_custom_ops = True
tfmodel = converter.convert() 
open ("model.tflite" , "wb") .write(tfmodel)

【讨论】:

以上是关于TFLite 转换器:为 keras 模型实现的 RandomStandardNormal,但不适用于纯 TensorFlow 模型的主要内容,如果未能解决你的问题,请参考以下文章

将 keras 模型从 pb 文件转换为 tflite 文件

来自自定义 keras 层的 tflite 转换器

如何将 TensorFlow 模型转换为 TFLite 模型

将 .tflite 转换为 .pb

将 Tensorflow Keras 模型(编码器 - 解码器)保存为 SavedModel 格式

如何更改解释器输出形状?