私はAndroidアプリケーションでTensorflowモデルを実行しようとしていますが、同じ訓練モデルでデスクトップ上のPython上で実行されるときとは異なる結果(誤った推論)を示します。AndroidとPythonで異なる結果をもたらす同じTensorflowモデル
モデルは文字を認識するためのシンプルなシーケンシャルCNNで、this number plate recognition networkと同じように、私のモデルには文字が既に切り取られているため、ウィンドウがありません。
は私が持っている:いるProtobuf(.pb)ファイルに保存されて
- モデル - パイソン/ Linuxの+ GPU
- 推論に、純粋なTensorflow上の別のコンピュータ上でテストした上でKerasでモデル化し、訓練を受けました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