【问题标题】:Tensorflow keras frozen .pb model returns bad results on androidTensorflow keras freeze .pb 模型在 android 上返回不好的结果
【发布时间】:2018-07-03 06:16:35
【问题描述】:

我使用 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 模型之前对其进行预处理。位图来自我手机上的摄像头。

//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 文件?还是我错误地将图像发送到冻结图?我被难住了。

【问题讨论】:

    标签: android python tensorflow keras protocol-buffers


    【解决方案1】:

    很难说,因为我不确定您的 Keras 模型的详细信息,但在移植到另一个平台时最棘手的部分是输入图像处理参数。你定义了imageMeanimageStd,但是你知道它们和Keras模型是一样的吗?

    为了调试它,我经常尝试通过 Python 和设备上的代码提供相同的图像(例如 Admiral Hopper),并确保得到相同的结果。

    【讨论】:

      【解决方案2】:

      如果您确定图像预处理步骤。那么问题可能和我的一样。我遇到了同样的问题,我找到了答案。更多说明是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);
      

      希望对你有帮助,

      【讨论】:

        猜你喜欢
        • 2018-04-28
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-19
        • 2018-01-08
        • 1970-01-01
        • 2019-11-28
        相关资源
        最近更新 更多