【发布时间】:2020-11-26 21:27:53
【问题描述】:
在向模型添加几层后,我正在尝试将模型转换为 TensorFlow Lite。我已经使用 Python 中的测试输入成功地运行了它们,并且它们运行良好。目标是允许模型接收 RGB 图像 (uint8),调整通道大小和打乱通道,以便使用 TensorFlow Lite 的 python 和平台之间的预处理完全一致(避免使用 Android 位图大小调整库或嵌入式系统大小调整方法)。我发现设备之间的预处理不一致。
任何其他操作也会发生这种情况。这让我觉得是Input() 层导致了这个问题。我不确定如何正确创建图层以使转换正常工作。
模型设置代码
input_shape = (None, None, 3) # Im using None here because I want the model to accept arbitrary image sizes.
input = Input(shape=input_shape, batch_size=1, dtype="uint8")
bn_axis = 3
bn_eps = 0.0001
x = ChannelReversal()(input) # A custom layer
x = Resizing(224, 224, interpolation='bilinear', name="Resize")(x)
x = DepthwiseNormalization([91.4953, 103.8827, 131.0912])(x) # Another custom layer
x = Conv2D(
64, (7, 7), use_bias=False, strides=(2, 2), padding='same',
name='conv1/7x7_s2')(x)
这里的错误是完全的荣耀
venv/lib/python3.8/site-packages/tensorflow/python/framework/op_def_library.py:742:0: note: see current operation: %1 = "tf.ReverseV2"(%arg0, %outputs_0) {device = ""} : (tensor<1x?x?x3x!tf.quint8>, tensor<1xi32>) -> tensor<1x?x?x3xui8>
error: 'tf.ReverseV2' op operand #0 must be tensor of bfloat16 type or 16-bit float or 32-bit float or 64-bit float or 1-bit signless integer or 16-bit signless integer or 32-bit signless integer or 64-bit signless integer or 8-bit signless integer or complex type with 64-bit float elements or complex type with 32-bit float elements or TensorFlow string type or 16-bit unsigned integer or 8-bit unsigned integer values, but got 'tensor<1x?x?x3x!tf.quint8>'
这是我的自定义层,虽然我不认为这是问题
from tensorflow.python.keras.engine.base_layer import Layer
from tensorflow.python.keras import backend as K
from tensorflow.python.ops import math_ops
import tensorflow as tf
class ChannelReversal(Layer):
"""Image color channel reversal layer (e.g. RGB -> BGR)."""
def __init__(self):
super(ChannelReversal, self).__init__()
def call(self, inputs):
return tf.reverse(inputs, axis=tf.constant([3]), name="channel_reversal")
# return inputs[..., ::-1]
class DepthwiseNormalization(Layer):
"""Channel specific normalisation"""
def __init__(self, mean=[0,0,0], stddev=[1.,1.,1.]):
super(DepthwiseNormalization, self).__init__()
self.mean = tf.broadcast_to(mean, [224,224,3])
self.stddev = tf.broadcast_to(stddev, [224,224,3])
def call(self, inputs):
if inputs.dtype != K.floatx():
inputs = math_ops.cast(inputs, K.floatx())
return (inputs - self.mean) / self.stddev
我可以通过删除 input = Input(shape=input_shape, batch_size=1, dtype="uint8") 中的dtype 参数来修复它,但是模型需要Float32,在使用它时会带来一个问题 TensorFlow Lite。
【问题讨论】:
-
tf.quint8似乎表明您正在量化您的 tflite 模型。是这样吗? -
不,我不想做任何量化
-
顺便说一句,如果将来有人看我的代码,我们实际上将预处理与模型的其余部分(Conv2D)分开,所以我们只需要在一个上运行
allocateTensors更小的模型,速度更快。
标签: tensorflow keras tensorflow-lite