【问题标题】:Tflite model giving different output in Android (ml vision) and PythonTflite 模型在 Android(ml vision)和 Python 中给出不同的输出
【发布时间】:2020-04-13 07:06:38
【问题描述】:

我正在使用 ML Vision api 从 FaceNet 模型创建嵌入,然后比较两个嵌入之间的余弦距离。 Android 版本和 Python 的输出差别很大。 Python 版本的性能优于 android 版本。可能是什么问题?我在两者中都使用了 FaceNet 模型。

我正在使用 ML 套件进行推理 https://firebase.google.com/docs/ml-kit/android/use-custom-models

我认为可能是java读取图像的方式引起的,因为android中制作的图像数组与python中相同图像的数组不同。

【问题讨论】:

    标签: java python android tensorflow kotlin


    【解决方案1】:

    所以我在ML vision docs关注谷歌文档时遇到了这个问题 在将图像输入分类器之前将图像转换为浮点数组的位置,如下所示:

    val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true)
    
    val batchNum = 0
    val input = Array(1) { Array(224) { Array(224) { FloatArray(3) } } }
    for (x in 0..223) {
        for (y in 0..223) {
            val pixel = bitmap.getPixel(x, y)
            // Normalize channel values to [-1.0, 1.0]. This requirement varies by
            // model. For example, some models might require values to be normalized
            // to the range [0.0, 1.0] instead.
            input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f
            input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f
            input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f
        }
    }
    

    然后我一步一步分析,发现获取像素的方式是错误的,和python做的完全不一样。

    然后我从this source 找到了这种方法,我用我的方法更改了该功能:

        private fun convertBitmapToByteBuffer(bitmap: Bitmap): ByteBuffer {
            val imgData = ByteBuffer.allocateDirect(4 * INPUT_SIZE * INPUT_SIZE * PIXEL_SIZE)
            imgData.order(ByteOrder.nativeOrder())
            val intValues = IntArray(INPUT_SIZE * INPUT_SIZE)
    
    
            imgData.rewind()
            bitmap.getPixels(intValues, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
            // Convert the image to floating point.
            var pixel = 0
            for (i in 0 until INPUT_SIZE) {
                for (j in 0 until INPUT_SIZE) {
                    val `val` = intValues[pixel++]
                    imgData.putFloat(((`val`.shr(16) and 0xFF) - IMAGE_MEAN)/IMAGE_STD)
                    imgData.putFloat(((`val`.shr(8) and 0xFF)- IMAGE_MEAN)/ IMAGE_STD)
                    imgData.putFloat(((`val` and 0xFF) - IMAGE_MEAN)/IMAGE_STD)
                }
            }
            return imgData;
       }
    

    它成功了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 2022-01-05
      相关资源
      最近更新 更多