简体   繁体   中英

Android TensorFlow Lite interpreter: How to fix "DataType error: cannot resolve DataType of java.lang.Float"

When running the TFLite interpreter giving as input a ByteBuffer containing floats, the application throws an exception:

"DataType error: cannot resolve DataType of java.lang.Float"

The model itself was trained on Keras, then converted to TF and then to TFLite.

For conversion I have used the TF (version 1.5.0) toco converter.

Input parameters for toco:

toco --input_file=converted.pb --output_file=model.tflite --input_format=TENSORFLOW_GRAPHDEF --input_shape=1,224,224,3 --input_array=main_input --output_array=main_output/Sigmoid --inference_type=FLOAT --output_format=TFLITE --input_type=FLOAT

Instead of the ByteBuffer I also have manually created a float[][][][] array with dimensions expected as input by the model: [1,224,224,3]

Leads to the same error as the ByteBuffer.

Please note that I am dividing the floats by 255 to get the pixel values in the range of [0,1].

import org.tensorflow.lite.Interpreter;
import java.nio.ByteBuffer;


public Interpreter tflite;

tflite = new Interpreter(loadModelFile(Test_TFLite.this,modelFile));

ByteBuffer bytebuffer_float = convertBitmapToByteBuffer_float(image, 1, 
    224, 3);

float out = 0;

tflite.run(bytebuffer_float,out);


private ByteBuffer convertBitmapToByteBuffer_float(Bitmap bitmap, int 
    BATCH_SIZE, int inputSize, int PIXEL_SIZE) {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * BATCH_SIZE * 
    inputSize * inputSize * PIXEL_SIZE); //float_size = 4 bytes
        byteBuffer.order(ByteOrder.nativeOrder());
        int[] intValues = new int[inputSize * inputSize];
        bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, 
    bitmap.getWidth(), bitmap.getHeight());
        int pixel = 0;
        for (int i = 0; i < inputSize; ++i) {
            for (int j = 0; j < inputSize; ++j) { 
                final int val = intValues[pixel++];


                byteBuffer.putFloat( ((val >> 16) & 0xFF)* (1.f/255.f)); 
                byteBuffer.putFloat( ((val >> 8) & 0xFF)* (1.f/255.f)); 
                byteBuffer.putFloat( (val & 0xFF)* (1.f/255.f)); 
            }
        }
        return byteBuffer;
    }

I expect a single float value in range [0,1] as an output. There is no actual output as the interpreter throws an exception.

"DataType error: cannot resolve DataType of java.lang.Float"

I've never used TF-Lite for Java myself. But, according to the docs , both arguments of tflite.run() have to be tensors. But for the output argument you are passing a single float only. So, I'm pretty sure this is the root cause of your error "cannot resolve DataType of java.lang.Float".

Note: also according to the docs, raw ByteBuffer s as well as multidimensional arrays of the supported data types ( float , int , long , byte ) are supported. So, both of your approaches, ByteBuffer and float[][][][] should work. You only have to do the same for the output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM