字节缓冲区的大小和形状不匹配。我在将我的 Ml 模型集成到 android 应用程序时遇到了这个错误

Posted

技术标签:

【中文标题】字节缓冲区的大小和形状不匹配。我在将我的 Ml 模型集成到 android 应用程序时遇到了这个错误【英文标题】:The size of byte buffer and the shape do not match.I am facing this error while integrating my Ml model in android app 【发布时间】:2022-01-13 18:06:16 【问题描述】:

我正在制作我的第一个 ML 集成 android 应用程序,我正在尝试将此 ocr 模型添加到我的应用程序中。但我正面临这个错误

Caused by: java.lang.IllegalArgumentException: The size of byte buffer and the shape do not match.
    at org.tensorflow.lite.support.common.SupportPreconditions.checkArgument(SupportPreconditions.java:104)
    at org.tensorflow.lite.support.tensorbuffer.TensorBuffer.loadBuffer(TensorBuffer.java:296)
    at org.tensorflow.lite.support.tensorbuffer.TensorBuffer.loadBuffer(TensorBuffer.java:323)
    at com.security.ml.MainActivity.onDetect(MainActivity.kt:36)
    at java.lang.reflect.Method.invoke(Native Method) 
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441) 
    at android.view.View.performClick(View.java:7585) 
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) 
    at android.view.View.performClickInternal(View.java:7541) 
    at android.view.View.access$3900(View.java:842) 
    at android.view.View$PerformClick.run(View.java:28875) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:255) 
    at android.app.ActivityThread.main(ActivityThread.java:8212) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049) 

这就是我尝试整合它的方式

        val model = Linear.newInstance(this)
    val imageview = findViewById<ImageView>(R.id.imageview)
    var bitmap = imageview.getDrawable().toBitmap()
    bitmap = Bitmap.createScaledBitmap(bitmap, 32, 32, true)

    val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 32, 32, 1), DataType.FLOAT32)

    val tensorImage = TensorImage(DataType.FLOAT32)
    tensorImage.load(bitmap)
    val byteBuffer = tensorImage.buffer

    inputFeature0.loadBuffer(byteBuffer)

    val outputs = model.process(inputFeature0)
    val outputFeature0 = outputs.outputFeature0AsTensorBuffer

    model.close()

    Toast.makeText(this, outputFeature0.floatArray[0].toString(),Toast.LENGTH_LONG).show()

我看到了许多其他相同的问题并尝试了这些解决方案,我尝试将 tensorBuffer 的大小更改 4 次,我尝试将 byteBuffer 直接传递给 model.process() 函数。 但他们都没有工作。 可能是什么问题,请帮忙。

【问题讨论】:

【参考方案1】:

您正在创建的位图很可能来自具有三个通道 RGB 的图像,因此您的缓冲区将是 32 x 32 x 3 = 3072

bitmap = Bitmap.createScaledBitmap(bitmap, 32, 32, true)

但您需要将Gray-Scale 图像发送到您的模型,因为它表明[1,32,32,1] 它只需要单个香奈儿,因此缓冲区应该是32 x 32 x 1 = 1024

val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 32, 32, 1), DataType.FLOAT32)

调试

有一种方法可以检查缓冲区。

Log.d("shape", byteBuffer.toString())
Log.d("shape", inputFeature0.buffer.toString())

并检查缓冲区的输出以找出其中的任何差异。

【讨论】:

以上是关于字节缓冲区的大小和形状不匹配。我在将我的 Ml 模型集成到 android 应用程序时遇到了这个错误的主要内容,如果未能解决你的问题,请参考以下文章

字节缓冲区的大小和形状不匹配(以前没有回答)

使用 OpenCV 识别模式

One-Hot-Encoding 训练和测试数据时的形状不匹配。在将 get_dummies 与管道一起使用时,Train_Data 具有比 Test_data 更多的虚拟列

缓冲区 dtype 不匹配,预期为 'SIZE_t' 但得到了 'long long'

为啥我在将我的 Electron 项目更新到最新版本后会看到“电子安全警告”?

OpenCL 缓冲区大小填充