如何解析张量流模型的字符串输出
How to parse String output of a tensorflow model
使用此处的代码创建了一个模型:https://gist.github.com/gaganmalhotra/1424bd3d0617e784976b29d5846b16b1
要获得 java 中概率的预测,可以使用以下代码完成:
public static void main(String[] args) {
Session session = SavedModelBundle.load("/Users/gagandeep.malhotra/Documents/SampleTF_projects/tf_iris_model/1510707746/", "serve").session();
Tensor x =
Tensor.create(
new long[] {2, 4},
FloatBuffer.wrap(
new float[] {
6.4f, 3.2f, 4.5f, 1.5f,
5.8f, 3.1f, 5.0f, 1.7f
}));
final String xName = "Placeholder:0";
final String scoresName = "dnn/head/predictions/probabilities:0";
List<Tensor<?>> outputs = session.runner()
.feed(xName, x)
.fetch(scoresName)
.run();
// Outer dimension is batch size; inner dimension is number of classes
float[][] scores = new float[2][3];
outputs.get(0).copyTo(scores);
System.out.println(Arrays.deepToString(scores));
}
但是如果我们想复制下面代码的预测类(字符串类型):
final String xName = "Placeholder:0";
final String className = "dnn/head/predictions/str_classes:0";
List<Tensor<?>> outputs = session.runner()
.feed(xName, x)
.fetch(className)
.run();
// Outer dimension is batch size; inner dimension is number of classes
String[][] classes = new String[2][1];
outputs.get(0).copyTo(classes);
System.out.println(Arrays.deepToString(classes));
我最终遇到这样的错误:
Exception in thread "main" java.lang.IllegalArgumentException: cannot copy Tensor with 2 dimensions into an object with 1
at org.tensorflow.Tensor.throwExceptionIfTypeIsIncompatible(Tensor.java:739)
at org.tensorflow.Tensor.copyTo(Tensor.java:450)
at deeplearning.IrisTFLoad.main(IrisTFLoad.java:71)
但维度与输出张量相同:[STRING 张量,形状为 [2, 1]]
PS: 签名定义如下 -
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 4)
name: Placeholder:0
The given SavedModel SignatureDef contains the following output(s):
outputs['class_ids'] tensor_info:
dtype: DT_INT64
shape: (-1, 1)
name: dnn/head/predictions/ExpandDims:0
outputs['classes'] tensor_info:
dtype: DT_STRING
shape: (-1, 1)
name: dnn/head/predictions/str_classes:0
outputs['logits'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 3)
name: dnn/head/logits:0
outputs['probabilities'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 3)
name: dnn/head/predictions/probabilities:0
Method name is: tensorflow/serving/predict
尝试过的事情:
张量张量=(张量)outputs.get(0);
byte[][][] 结果 = tensor.copyTo(new byte[2][1][]);
但错误如下:
Exception in thread "main" java.lang.IllegalStateException: invalid DataType(7)
at org.tensorflow.Tensor.readNDArray(Native Method)
at org.tensorflow.Tensor.copyTo(Tensor.java:451)
at deeplearning.IrisTFLoad.main(IrisTFLoad.java:74)
DT_STRING
类型的 TensorFlow 张量包含 arbitrary byte sequences 作为元素,而不是 Java String
s(字符序列)。
因此,你想要的是这样的:
byte[][][] classes = new byte[2][1][];
outputs.get(0).copyTo(classes);
如果你想获得 Java String
对象,那么你需要知道你的模型产生 类 的编码,然后可以做类似的事情(假设 UTF-8 编码):
String[][] classesStrings = new String[2][1];
for (int i = 0; i < classes.length; ++i) {
for (int j = 0; j < classes[i].length; ++j) {
classesString[i][j] = new String(classes[i][j], UTF_8);
}
}
希望对您有所帮助。
您可能还会发现 unittest 很有启发性。
使用此处的代码创建了一个模型:https://gist.github.com/gaganmalhotra/1424bd3d0617e784976b29d5846b16b1
要获得 java 中概率的预测,可以使用以下代码完成:
public static void main(String[] args) {
Session session = SavedModelBundle.load("/Users/gagandeep.malhotra/Documents/SampleTF_projects/tf_iris_model/1510707746/", "serve").session();
Tensor x =
Tensor.create(
new long[] {2, 4},
FloatBuffer.wrap(
new float[] {
6.4f, 3.2f, 4.5f, 1.5f,
5.8f, 3.1f, 5.0f, 1.7f
}));
final String xName = "Placeholder:0";
final String scoresName = "dnn/head/predictions/probabilities:0";
List<Tensor<?>> outputs = session.runner()
.feed(xName, x)
.fetch(scoresName)
.run();
// Outer dimension is batch size; inner dimension is number of classes
float[][] scores = new float[2][3];
outputs.get(0).copyTo(scores);
System.out.println(Arrays.deepToString(scores));
}
但是如果我们想复制下面代码的预测类(字符串类型):
final String xName = "Placeholder:0";
final String className = "dnn/head/predictions/str_classes:0";
List<Tensor<?>> outputs = session.runner()
.feed(xName, x)
.fetch(className)
.run();
// Outer dimension is batch size; inner dimension is number of classes
String[][] classes = new String[2][1];
outputs.get(0).copyTo(classes);
System.out.println(Arrays.deepToString(classes));
我最终遇到这样的错误:
Exception in thread "main" java.lang.IllegalArgumentException: cannot copy Tensor with 2 dimensions into an object with 1
at org.tensorflow.Tensor.throwExceptionIfTypeIsIncompatible(Tensor.java:739)
at org.tensorflow.Tensor.copyTo(Tensor.java:450)
at deeplearning.IrisTFLoad.main(IrisTFLoad.java:71)
但维度与输出张量相同:[STRING 张量,形状为 [2, 1]]
PS: 签名定义如下 -
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 4)
name: Placeholder:0
The given SavedModel SignatureDef contains the following output(s):
outputs['class_ids'] tensor_info:
dtype: DT_INT64
shape: (-1, 1)
name: dnn/head/predictions/ExpandDims:0
outputs['classes'] tensor_info:
dtype: DT_STRING
shape: (-1, 1)
name: dnn/head/predictions/str_classes:0
outputs['logits'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 3)
name: dnn/head/logits:0
outputs['probabilities'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 3)
name: dnn/head/predictions/probabilities:0
Method name is: tensorflow/serving/predict
尝试过的事情:
张量张量=(张量)outputs.get(0); byte[][][] 结果 = tensor.copyTo(new byte[2][1][]);
但错误如下:
Exception in thread "main" java.lang.IllegalStateException: invalid DataType(7)
at org.tensorflow.Tensor.readNDArray(Native Method)
at org.tensorflow.Tensor.copyTo(Tensor.java:451)
at deeplearning.IrisTFLoad.main(IrisTFLoad.java:74)
DT_STRING
类型的 TensorFlow 张量包含 arbitrary byte sequences 作为元素,而不是 Java String
s(字符序列)。
因此,你想要的是这样的:
byte[][][] classes = new byte[2][1][];
outputs.get(0).copyTo(classes);
如果你想获得 Java String
对象,那么你需要知道你的模型产生 类 的编码,然后可以做类似的事情(假设 UTF-8 编码):
String[][] classesStrings = new String[2][1];
for (int i = 0; i < classes.length; ++i) {
for (int j = 0; j < classes[i].length; ++j) {
classesString[i][j] = new String(classes[i][j], UTF_8);
}
}
希望对您有所帮助。 您可能还会发现 unittest 很有启发性。