1

我正在测试 Google Cloud AutoML 视觉,我已经完成了训练过程,有一个导出的边缘设备 tflite 模型,超过 10 万张图像,25 个标签。

按照这两个教程中的说明和以下存储库中的代码:https: //cloud.google.com/vision/automl/docs/edge-quickstart https://cloud.google.com/vision/automl/docs/tflite -android 教程 https://github.com/googlecodelabs/tensorflow-for-poets-2/tree/master/android/tflite

我假设问题不在于自定义 tflite 问题,而是本教程未解决的某种兼容性问题(错误或因为它已过时?)

上面 github 存储库中包含的具有预训练模型的示例应用程序无需任何更改即可工作。当我换出 tflite 包并进行教程要求的代码更改时,我遇到了 BufferOverflowException

我假设问题不在于自定义 tflite 问题,而是本教程未解决的某种兼容性问题(错误或因为它已过时?)

上面 github 存储库中包含的具有预训练模型的示例应用程序无需任何更改即可工作。当我换出 tflite 包并进行教程要求的代码更改时,我遇到了 BufferOverflowException

try/catch 块中的代码崩溃(由我添加以查看更多发生的情况)

'''
private void convertBitmapToByteBuffer(Bitmap bitmap) {
if (imgData == null) {
  return;
}
imgData.rewind();
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
// Convert the image to floating point.
int pixel = 0;
long startTime = SystemClock.uptimeMillis();
for (int i = 0; i < DIM_IMG_SIZE_X; ++i) {
  for (int j = 0; j < DIM_IMG_SIZE_Y; ++j) {
    final int val = intValues[pixel++];
    try
    {
      imgData.putFloat((((val >> 16) & 0xFF))/IMAGE_STD);
      imgData.putFloat((((val >> 8) & 0xFF))/IMAGE_STD);
      imgData.putFloat((((val) & 0xFF))/IMAGE_STD);
    }
    catch (BufferOverflowException e)
    {
      Log.e("TfLiteCameraDemo", "Exception caught: ", e);
    }
  }
}
long endTime = SystemClock.uptimeMillis();
Log.d(TAG, "Timecost to put values into ByteBuffer: " + Long.toString(endTime - startTime));
}
'''

按照上面链接中的教程的说明,导入的 tflite 模型会崩溃。

4

1 回答 1

0

我意识到这是一篇较旧的帖子,但我遇到了同样的问题并找到了解决方案。也许张贴会在未来帮助别人。

Tensorflow 部分想要的缓冲区是 150528 字节。通过使用上面的 putFloat(),代码试图将 4x(float = 4 字节)的数据放入 imgData 缓冲区。我试着让缓冲区更大,这会产生不同的错误。最终起作用的是将数据从浮点数转换为字节数。见下文。

原文:(因缓冲区溢出错误而崩溃)

imgData.putFloat((((val >> 16) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
imgData.putFloat((((val >> 8) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
imgData.putFloat((((val) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);

已修改:(这在我的 Galaxy Note9 上运行时不会崩溃。不过,它在准确识别方面做得并不好。)

imgData.put((byte) ((byte) (((val >> 16) & 0xFF)- IMAGE_MEAN)/IMAGE_STD));
imgData.put((byte) ((byte) (((val >> 8) & 0xFF)-IMAGE_MEAN)/IMAGE_STD));
imgData.put((byte) (((byte) ((val) & 0xFF)-IMAGE_MEAN)/IMAGE_STD));
于 2019-12-06T20:49:04.507 回答