我使用Keras在IncpetionV3上创建了我的模型,并使用以下python代码将其导出到 .pb 文件中:
MODEL_NAME = 'Model_all1'
def export_model(saver, model, input_node_names, output_node_name):
tf.train.write_graph(K.get_session().graph_def, 'out_all2', MODEL_NAME + '_graph.pbtxt')
saver.save(K.get_session(), 'out_all2/' + MODEL_NAME + '.chkp')
freeze_graph.freeze_graph('out_all2/' + MODEL_NAME + '_graph.pbtxt', None,
False, 'out_all2/' + MODEL_NAME + '.chkp', output_node_name,
"save/restore_all", "save/Const:0",
'out_all2/final_' + MODEL_NAME + '.pb', True, "")
print("graph saved!")
export_model(tf.train.Saver(), model, ["input_3"], "dense_6/Softmax")
然后我尝试将我的模型加载到我的Android应用程序中。 对于我的应用程序,我使用以下代码预先处理我的图像,然后将其发送到 .pb 模型。 Bitmap来自我手机上的相机。
//scaled the bitmap down
Bitmap bitmap = Bitmap.createScaledBitmap(imageBitmap, PIXEL_WIDTH, PIXEL_WIDTH, true);
float pixels[] = getPixelData(bitmap);
public static float[] getPixelData(Bitmap imageBitmap) {
if (imageBitmap == null) {
return null;
}
int width = imageBitmap.getWidth();
int height = imageBitmap.getHeight();
int inputSize = 299;
int imageMean = 155;
float imageStd = 255.0f;
int[] pixels = new int[width * height];
float[] floatValues = new float[inputSize * inputSize * 3];
imageBitmap.getPixels(pixels, 0, imageBitmap.getWidth(), 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight());
for (int i = 0; i < pixels.length; ++i) {
final int val = pixels[i];
floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - imageMean) / imageStd;
floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
}
return floatValues;
}
下面显示我识别的图像代码,链接到我在Android上加载的.pb文件
public ArrayList<Classification> recognize(final float[] pixels) {
//using the interface
//input size
tfHelper.feed(inputName, pixels, 1, inputSize, inputSize, 3);
//get the possible outputs
tfHelper.run(outputNames, logStats);
//get the output
tfHelper.fetch(outputName, outputs);
// Find the best classifications.
PriorityQueue<Recognition> pq =
new PriorityQueue<Recognition>(
3,
new Comparator<Recognition>() {
@Override
public int compare(Recognition lhs, Recognition rhs) {
// Intentionally reversed to put high confidence at the head of the queue.
return Float.compare(rhs.getConfidence(), lhs.getConfidence());
}
});
for (int i = 0; i < outputs.length; ++i) {
if (outputs[i] > THRESHOLD) {
pq.add(
new Classifier.Recognition(
"" + i, labels.size() > i ? labels.get(i) : "unknown", outputs[i], null));
}
}
final ArrayList<Recognition> recognitions = new ArrayList<Recognition>();
int recognitionsSize = Math.min(pq.size(), MAX_RESULTS);
for (int i = 0; i < recognitionsSize; ++i) {
recognitions.add(pq.poll());
}
Trace.endSection(); // "recognizeImage"
//fit into classification list
ArrayList<Classification> anslist = new ArrayList<>();
for (int i = 0; i < recognitions.size(); i++) {
Log.d("classification",recognitions.get(i).getTitle() +" confidence : "+ recognitions.get(i).getConfidence());
Classification ans = new Classification();
ans.update(recognitions.get(i).getConfidence(),recognitions.get(i).getTitle());
anslist.add(ans);
}
return anslist;
}
在我的测试中,在我生成冻结图模型之前, .pb 文件。我的模型的准确性非常高。但是,当我将其加载到我的Android应用程序时,我在Android上的模型返回的预测结果到处都是。
我已经测试了很长时间,我无法找到问题所在。有没有人有任何见解?我是否生成了错误的 .pb 文件?或者我是否错误地将图像发送到冻结图表?我很难过。
答案 0 :(得分:0)
很难说,因为我不确定你的Keras模型的细节,但是在移植到另一个平台时最合适的部分之一是输入图像处理参数。您已定义imageMean
和imageStd
,但是您知道它们与Keras模型相同吗?
要调试这个,我会经常尝试通过Python和设备上的代码提供相同的图像(例如Admiral Hopper),并确保得到相同的结果。
答案 1 :(得分:0)
如果您确定图像预处理步骤。然后问题可能和我的一样。我遇到了同样的问题,我找到了答案。 here有更多说明。我猜你除了以下所做的所有步骤都是我的。
您的问题可能在于色彩通道还原。 imageBitmap.getPixels
将颜色通道从BGR反转为RGB。如果这是图像预处理的一部分,您只需要将它们转换回BGR。
使用以下代码执行此操作:
floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - imageMean) / imageStd;
floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
floatValues[i * 3 + 2] = ((val & 0xFF) - imageMean) / imageStd;
// reverse the color orderings to BGR.
floatValues[i*3 + 2] = Color.red(val);
floatValues[i*3 + 1] = Color.green(val);
floatValues[i*3] = Color.blue(val);
希望有帮助,