我想在我的Android应用程序上运行Tensorflow模型,但与在桌面上运行Python时相同的训练模型会给出不同的结果(错误推理)。在Android和Python上给出不同结果的相同Tensorflow模型
该模型是一个简单的顺序CNN识别字符,很像this number plate recognition network,减去窗口,因为我的模型已经将角色裁剪到位。
我:
- 模型保存在protobuf的(.pb)文件 - 建模和训练有素的Keras关于Python/Linux的+ GPU
- 推论是在不同的计算机上测试纯Tensorflow,以确保Keras不是罪魁祸首。在这里,结果如预期。
- Tensorflow 1.3.0正在Python和Android上使用。从Python上的PIP和Android上的jcenter安装。
- Android上的结果并不像预期的结果。
- 输入是129 * 45 RGB图像,所以是129 * 45 * 3数组,输出是4 * 36数组(代表0-9和a-z中的4个字符)。
我用this code将Keras模型保存为.pb文件。
Python代码,此按预期工作:
test_image = [ndimage.imread("test_image.png", mode="RGB").astype(float)/255]
imTensor = np.asarray(test_image)
def load_graph(model_file):
graph = tf.Graph()
graph_def = tf.GraphDef()
with open(model_file, "rb") as f:
graph_def.ParseFromString(f.read())
with graph.as_default():
tf.import_graph_def(graph_def)
return graph
graph=load_graph("model.pb")
with tf.Session(graph=graph) as sess:
input_operation = graph.get_operation_by_name("import/conv2d_1_input")
output_operation = graph.get_operation_by_name("import/output_node0")
results = sess.run(output_operation.outputs[0],
{input_operation.outputs[0]: imTensor})
Android的代码,基于this example;这给出了看似随机的结果:
Bitmap bitmap;
try {
InputStream stream = getAssets().open("test_image.png");
bitmap = BitmapFactory.decodeStream(stream);
} catch (IOException e) {
e.printStackTrace();
}
inferenceInterface = new TensorFlowInferenceInterface(context.getAssets(), "model.pb");
int[] intValues = new int[129*45];
float[] floatValues = new float[129*45*3];
String outputName = "output_node0";
String[] outputNodes = new String[]{outputName};
float[] outputs = new float[4*36];
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for (int i = 0; i < intValues.length; ++i) {
final int val = intValues[i];
floatValues[i * 3 + 0] = ((val >> 16) & 0xFF)/255;
floatValues[i * 3 + 1] = ((val >> 8) & 0xFF)/255;
floatValues[i * 3 + 2] = (val & 0xFF)/255;
}
inferenceInterface.feed("conv2d_1_input", floatValues, 1, 45, 129, 3);
inferenceInterface.run(outputNodes, false);
inferenceInterface.fetch(outputName, outputs);
任何帮助,非常感谢!
'(val&0xff)/ 255'等表达式是否真的会产生浮点结果?根据我的理解,分配的右侧将产生一个整数,即每次都为0。 – Vroomfondel
哦,哇,你是对的!我非常关注事物的Tensorflow方面,我完全错过了这一点。它仍然没有给我正确的结果,但是这绝对让我有一个开始的地方! – rednuht
@Vroomfondel - 如果您想将您的评论添加为问题的答案,我会很乐意接受这个答案。我得到了很多改进的结果,我认为有些差异可归因于精度问题。 – rednuht