【问题标题】:TensorFlow lite conversion: error: op operands must be tensor of 8-bit unsigned integer, but got tensor<1x?x?x3x!tf.quint8>TensorFlow lite 转换:错误:op 操作数必须是 8 位无符号整数的张量,但得到 tensor<1x?x?x3x!tf.quint8>
【发布时间】: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


【解决方案1】:

我的解决方法是在模型中使用 float32。这确实意味着我在将输入传递到模型之前对其进行了转换,但这可以通过 TensorFlow lite 支持库来完成。看起来这可能是转换为 TensorFlow Lite 的错误。

TensorBuffer imageBuffer = TensorBuffer.createFrom(image.getTensorBuffer(), DataType.FLOAT32);会在图片的数据类型与FLOAT32不匹配时自动转换。

【讨论】:

    猜你喜欢
    • 2022-11-19
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多