首页 > 解决方案 > tfliteGpuDelegate 调用写入缓冲区失败的源数据大于缓冲区

问题描述

我按照https://www.tensorflow.org/lite/performance/gpu中的步骤将 gpu 添加到 tflite 解释器。一个名为 tensorflow/lite/jave/demo 的 android 项目给出的 mobilenet 模型可以在 Pixel 2 上使用这个项目。但是,当它被放入另一个项目时,代码如下。这里有错误:

TfLiteGpuDelegate Invoke: Write to buffer failed. Source data is larger than buffer
Node number 31 (TfLiteGpuDelegateV2) failed to invoke.

imgData, outputClasses 已经检查过,并且与 tensorflow/lite/jave/demo 项目中的大小相同。

TfLite 和 TfLiteGpu 的版本也与 tensorflow/lite/jave/demo 项目中的相同。

import  org.tensorflow.lite.TensorFlowLite;
import org.tensorflow.lite.gpu.GpuDelegate;

/**
 * Wrapper for frozen detection models trained using the Tensorflow Object Detection API:
 * github.com/tensorflow/models/tree/master/research/object_detection
 */
public class TFLiteObjectDetectionAPIModel implements Classifier {
  private static final Logger LOGGER = new Logger();

  // Only return this many results.
  private static final int NUM_DETECTIONS = 1001; // hand landmark ,21, mobilenet, 1001
  // Float model
  private static final float IMAGE_MEAN = 128.0f;
  private static final float IMAGE_STD = 128.0f;
  private boolean isModelQuantized;
  private int inputSize;
  private Vector<String> labels = new Vector<String>();
  private int[] intValues;
  private float[][][] outputLocations;
  private float[][] outputClasses;
  private float[][] outputScores;
  private float[] numDetections;

  private GpuDelegate gpuDelegate = new GpuDelegate();
  private final Interpreter.Options options = (new Interpreter.Options()).addDelegate(gpuDelegate);
  private ByteBuffer imgData;

  private Interpreter tfLite;
  private ArrayList<Recognition> recognitions = new ArrayList<Recognition>();

  private TFLiteObjectDetectionAPIModel() {}

  /** Memory-map the model file in Assets. */
  private static MappedByteBuffer loadModelFile(AssetManager assets, String modelFilename)
      throws IOException {
    FileInputStream inputStream = new FileInputStream(new File("/sdcard/sunny/data/"+modelFilename+".tflite"));

    FileChannel fileChannel = inputStream.getChannel();
    long startOffset = fileChannel.position();
    long declaredLength = fileChannel.size();
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
  }

  /**
   * Initializes a native TensorFlow session for classifying images.
   *
   * @param assetManager The asset manager to be used to load assets.
   * @param modelFilename The filepath of the model GraphDef protocol buffer.
   * @param labelFilename The filepath of label file for classes.
   * @param inputSize The size of image input
   * @param isQuantized Boolean representing model is quantized or not
   */
  public static Classifier create(
      final AssetManager assetManager,
      final String modelFilename,
      final String labelFilename,
      final int inputSize,
      final boolean isQuantized)
      throws IOException {
    final TFLiteObjectDetectionAPIModel d = new TFLiteObjectDetectionAPIModel();

    InputStream labelsInput = null;
    String actualFilename = labelFilename.split("file:///android_asset/")[1];
    labelsInput = assetManager.open(actualFilename);
    BufferedReader br = null;
    br = new BufferedReader(new InputStreamReader(labelsInput));
    String line;
    while ((line = br.readLine()) != null) {
      LOGGER.w(line);
      d.labels.add(line);
    }
    br.close();

    d.inputSize = inputSize;
    try {
      d.tfLite = new Interpreter(loadModelFile(assetManager, modelFilename),d.options);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    d.isModelQuantized = isQuantized;
    // Pre-allocate buffers.
    int numBytesPerChannel;
    if (isQuantized) {
      numBytesPerChannel = 1; // Quantized
    } else {
      numBytesPerChannel = 4; // Floating point
    }
    d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * 4);
    d.imgData.order(ByteOrder.nativeOrder());
    d.intValues = new int[d.inputSize * d.inputSize];

    d.outputClasses = new float[1][NUM_DETECTIONS];

    return d;
  }

  @Override
  public List<Recognition> processImage(final AssetManager assetManager, Classifier.Recognition.inputFormat imageFormat, int[] intValues){
    Trace.beginSection("preprocessBitmap");

    imgData.rewind();
    for (int i = 0; i < inputSize; ++i) {
      for (int j = 0; j < inputSize; ++j) {
        int pixelValue = intValues[i * inputSize + j];
        if (isModelQuantized) {
          // Quantized model
          imgData.put((byte) ((pixelValue >> 16) & 0xFF));
          imgData.put((byte) ((pixelValue >> 8) & 0xFF));
          imgData.put((byte) (pixelValue & 0xFF));
        } else { // Float model
          imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
          imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
          imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
        }
      }
    }
    Trace.endSection(); // preprocessBitmap

    // Copy the input data into TensorFlow.
    Trace.beginSection("feed");
    outputClasses = new float[1][NUM_DETECTIONS];
    Trace.endSection();

    // Run the inference call.
    Trace.beginSection("run");
    tfLite.run(imgData, outputClasses);
    Trace.endSection();

    return recognitions;
  }


  @Override
  public void enableStatLogging(final boolean logStats) {}

  @Override
  public String getStatString() {
    return "";
  }

  @Override
  public void close() {
    tfLite.close();
    tfLite = null;
    recognitions.clear();
    recognitions=null;
    gpuDelegate.close();
    gpuDelegate = null;
}

标签: pythontensorflowtensorflow-lite

解决方案


推荐阅读