2
$\begingroup$

I am trying to run Tensorflow for image recognition (classification) in Java (JSE not Android).

I am using the code from here, and here.

It works for Inceptionv3 models, and for models retrained from Inceptionv3.

But for MobileNet models it does not work, (such as following this article).

The code works, but gives the wrong results (wrong classify labels). What code/settings are required to use MobileNet from Java?

The code that works for Inceptionv3 is

try (Tensor image = Tensor.create(imageBytes)) {
            float[] labelProbabilities = executeInceptionGraph(graphDef, image);
            int bestLabelIdx = maxIndex(labelProbabilities);
            result.setText("");
            result.setText(String.format(
                            "BEST MATCH: %s (%.2f%% likely)",
                            labels.get(bestLabelIdx), labelProbabilities[bestLabelIdx] * 100f));
            System.out.println(
                    String.format(
                            "BEST MATCH: %s (%.2f%% likely)",
                            labels.get(bestLabelIdx), labelProbabilities[bestLabelIdx] * 100f));
        }

This works of Inceptionv3 models, but not MobileNet, Gives the error, "Expects args[0] to be float but string is provided"

For MobileNet we tried the code,

try (Graph g = new Graph()) {
  GraphBuilder b = new GraphBuilder(g);
  // Some constants specific to the pre-trained model at:
  // https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
  //
  // - The model was trained with images scaled to 224x224 pixels.
  // - The colors, represented as R, G, B in 1-byte each were converted to
  //   float using (value - Mean)/Scale.
  final int H = 224;
  final int W = 224;
  final float mean = 128f;
  final float scale = 1f;

  // Since the graph is being constructed once per execution here, we can use a constant for the
  // input image. If the graph were to be re-used for multiple input images, a placeholder would
  // have been more appropriate.
  final Output<String> input = b.constant("input", imageBytes);
  final Output<Float> output =
      b.div(
          b.sub(
              b.resizeBilinear(
                  b.expandDims(
                      b.cast(b.decodeJpeg(input, 3), Float.class),
                      b.constant("make_batch", 0)),
                  b.constant("size", new int[] {H, W})),
              b.constant("mean", mean)),
          b.constant("scale", scale));
  try (Session s = new Session(g)) {
    return s.runner().fetch(output.op().name()).run().get(0).expect(Float.class);
  }
}

This works, but gives the wrong labels.

$\endgroup$
  • $\begingroup$ Have you found an answer to your question? Did you manage to get MobileNet to run without using TensorFlow lite? $\endgroup$ – Henry Aug 25 '18 at 10:49
  • 1
    $\begingroup$ No, we gave up running Tensorflow in Java, and switched to Python. $\endgroup$ – James Aug 26 '18 at 12:30
  • $\begingroup$ Thanks, I am currently also failing at setting up MobileNet. I might switch to Python, too. $\endgroup$ – Henry Aug 26 '18 at 12:52
0
$\begingroup$

Don't give to use in java :)

I had the same problem, try to change the scale value, I had the same labels from java and python after that.

        // - The model was trained with images scaled to 224x224 pixels.
        // - The colors, represented as R, G, B in 1-byte each were converted to
        // float using (value - Mean)/Scale.
        final int H = 224;
        final int W = 224;
        final float mean = 117f;
        final float scale = 255f;
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.