Tensorflow.lite 模型在 Android 应用程序中产生错误(不同)的结果?

Tensorflow.lite model produces wrong (different) results in Android app?

我做了一个图片分类模型,并转成了tflite格式。 然后,我使用 tf.lite.Interpreter 在 Python 中验证了 tflite 模型——它为我的测试图像生成了与原始模型相同的结果。这是 colab link to verify.

然后我使用 Android Studio ML Model Binding 和来自 Android studio 的确切示例代码将其嵌入示例 Android 应用程序。 这是 main activity code,您也可以使用此 link 导航到完整的 android 项目。

val assetManager = this.assets
val istr = assetManager.open("test_image.JPG") //The same image
val b = BitmapFactory.decodeStream(istr)

val model = Model2.newInstance(this) //Model definition generated by Android Studio

// Creates inputs for reference.
val image = TensorImage.fromBitmap(b)

// Runs model inference and gets result.
val outputs = model.process(image)
val probability = outputs.probabilityAsCategoryList
probability.sortByDescending { it.score }
val top9 = probability.take(9)

this.findViewById<TextView>(R.id.results_text).text = top9.toString()

然后对于相同的模型和相同的输入图像,我在 Android 上得到完全不同的结果。

以下是与我在 Python 中的初始模型匹配的结果:

这是我在 Android 应用中得到的错误结果:

模型和测试图像的链接在两个示例中都有,但我会再次post将它们放入问题中:

tflite model

test image

我想这与模型的input/output 格式有关。或者图像在 python 和 android 中的解释不同。或者 metadata I added to the model 不知何故是错误的。无论如何,我已经尽一切努力来定位问题,但现在我被卡住了。

如何修复我的模型或 Android 代码,使其产生与我的 python 代码相同的结果?

我已经找到并解决了这个问题: 我来自 this tutorial 的模型包含一个内置图像规范化层。图像归一化是将标准 0-255 图像颜色值转换为 0.0-1.0 浮点值,适用于机器学习。

但是我用于 tflite 模型的元数据包含 2 个用于外部标准化的参数:均值和标准差。 每个值的公式为:normalized_value = (value - mean) / std 由于我的模型处理自己的归一化,我需要通过设置 mean = 0std = 1 来关闭外部归一化。 这样我会得到 normalized_value = value.

因此,将 tflite 元数据参数设置为:

    image_min=0,
    image_max=255.0,
    mean=[0.0],
    std=[1.0]

修复了双重规范化问题,我的模型现在在 Android 应用程序中生成 correct results