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 文件
如何将 TensorFlow 模型转换为 TFLite 模型