Android TensorFlow Lite interpreter: How to fix "DataType error: cannot resolve DataType of java.lang.Float"
Android TensorFlow Lite interpreter: How to fix "DataType error: cannot resolve DataType of java.lang.Float"
当 运行 TFLite 解释器将包含浮点数的 ByteBuffer 作为输入时,应用程序抛出异常:
"DataType error: cannot resolve DataType of java.lang.Float"
模型本身是在 Keras 上训练的,然后转换为 TF,然后转换为 TFLite。
对于转换,我使用了 TF(1.5.0 版)toco 转换器。
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
我还手动创建了一个 float[][][][] 数组,而不是 ByteBuffer,其尺寸预期为模型输入:[1,224,224,3]
导致与 ByteBuffer 相同的错误。
请注意,我将浮点数除以 255 以获得 [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;
}
我希望输出 [0,1] 范围内的单个浮点值。由于解释器抛出异常,因此没有实际输出。
"DataType error: cannot resolve DataType of java.lang.Float"
我自己 Java 从未使用过 TF-Lite。
但是,根据 docs,tflite.run()
的两个参数都必须是张量。但是对于 output
参数,您只传递了一个 float
。所以,我很确定这是你错误 "cannot resolve DataType of java.lang.Float".
的根本原因
注意:同样根据文档,原始 ByteBuffer
s 以及支持的数据类型的多维数组(float
、int
、long
、byte
) 支持。因此,您的两种方法 ByteBuffer
和 float[][][][]
都应该有效。您只需对输出执行相同的操作即可。
当 运行 TFLite 解释器将包含浮点数的 ByteBuffer 作为输入时,应用程序抛出异常:
"DataType error: cannot resolve DataType of java.lang.Float"
模型本身是在 Keras 上训练的,然后转换为 TF,然后转换为 TFLite。
对于转换,我使用了 TF(1.5.0 版)toco 转换器。
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
我还手动创建了一个 float[][][][] 数组,而不是 ByteBuffer,其尺寸预期为模型输入:[1,224,224,3]
导致与 ByteBuffer 相同的错误。
请注意,我将浮点数除以 255 以获得 [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;
}
我希望输出 [0,1] 范围内的单个浮点值。由于解释器抛出异常,因此没有实际输出。
"DataType error: cannot resolve DataType of java.lang.Float"
我自己 Java 从未使用过 TF-Lite。
但是,根据 docs,tflite.run()
的两个参数都必须是张量。但是对于 output
参数,您只传递了一个 float
。所以,我很确定这是你错误 "cannot resolve DataType of java.lang.Float".
注意:同样根据文档,原始 ByteBuffer
s 以及支持的数据类型的多维数组(float
、int
、long
、byte
) 支持。因此,您的两种方法 ByteBuffer
和 float[][][][]
都应该有效。您只需对输出执行相同的操作即可。