我正在尝试在 Java(JSE 而不是 Android)中运行 Tensorflow 进行图像识别(分类)。
它适用于 Inceptionv3 模型,以及从 Inceptionv3 重新训练的模型。
但是对于 MobileNet 模型,它不起作用,(比如下面这篇文章)。
该代码有效,但给出了错误的结果(错误的分类标签)。从 Java 中使用 MobileNet 需要哪些代码/设置?
适用于 Inceptionv3 的代码是
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));
}
这适用于 Inceptionv3 模型,但不适用于 MobileNet,会给出错误“期望 args[0] 为浮点数,但提供了字符串”
对于 MobileNet,我们尝试了代码,
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);
}
}
这有效,但给出了错误的标签。