如何从 Java 中的示例对象创建张量?
How can I create a Tensor from an Example object in Java?
我的用例:
我正在尝试使用 libtensorflow_jni.
在我们现有的 JVM 服务中为 python 训练的模型提供服务
现在我可以使用 SavedModelBundle.load()
加载模型了。但我发现很难将请求输入模型。由于我的用户请求不是简单的标量矩阵,而是特征图,例如:
{'gender':1, 'age': 20, 'country': 100, other features ...}
通过搜索张量流教程,我发现 Example 协议缓冲区可能适合这里,因为它基本上包含一个功能列表。但我不确定如何将其转换为 Java Tensor 对象。
如果我直接使用序列化的 Example 对象创建 Tensor,TensorFlow 运行时似乎对数据类型不满意。例如,我执行以下操作,
Tensor inputTensor = Tensor.create(example.toByteArray());
s.runner().feed(inputTensorName, inputTensor).fetch(outputTensorName).run().get(0);
我会得到一个 IllegalArgumentException:
java.lang.IllegalArgumentException: Expected serialized to be a vector, got shape: []
如果你们碰巧知道或有相同的用例,你们能否阐明我如何从这里继续前进?
谢谢!
查看您的错误消息,问题似乎在于您的模型需要一个字符串张量向量(很可能对应于一批序列化的 Example
协议缓冲区消息,可能来自 tf.parse_example
) 但是你给它提供了一个标量字符串张量。
不幸的是,在解决 issue #8531 之前,Java API 无法创建 Tensor
字符串,除了标量。一旦这个问题得到解决,事情就会变得容易。
与此同时,您可以通过构建 TensorFlow "model" 将标量字符串转换为大小为 1 的向量来解决此问题:)。这可以通过这样的方式完成:
// A TensorFlow "model" that reshapes a string scalar into a vector.
// Should be much prettier once https://github.com/tensorflow/tensorflow/issues/7149
// is resolved.
private static class Reshaper implements AutoCloseable {
Reshaper() {
this.graph = new Graph();
this.session = new Session(graph);
this.in =
this.graph.opBuilder("Placeholder", "in")
.setAttr("dtype", DataType.STRING)
.build()
.output(0);
try (Tensor shape = Tensor.create(new int[] {1})) {
Output vectorShape =
this.graph.opBuilder("Const", "vector_shape")
.setAttr("dtype", shape.dataType())
.setAttr("value", shape)
.build()
.output(0);
this.out =
this.graph.opBuilder("Reshape", "out").addInput(in).addInput(vectorShape).build().output(0);
}
}
@Override
public void close() {
this.session.close();
this.graph.close();
}
public Tensor vector(Tensor input) {
return this.session.runner().feed(this.in, input).fetch(this.out).run().get(0);
}
private final Graph graph;
private final Session session;
private final Output in;
private final Output out;
}
通过上面的内容,您可以将示例原型张量转换为向量,然后将其输入到您感兴趣的模型中,如下所示:
Tensor inputTensor = null;
try (Tensor scalar = Tensor.create(example.toByteArray())) {
inputTensor = reshaper.vector(scalar);
}
s.runner().feed(inputTensorName, inputTensor).fetch(outputTensorName).run().get(0);
有关详细信息,see this example on github
希望对您有所帮助!
我的用例: 我正在尝试使用 libtensorflow_jni.
在我们现有的 JVM 服务中为 python 训练的模型提供服务现在我可以使用 SavedModelBundle.load()
加载模型了。但我发现很难将请求输入模型。由于我的用户请求不是简单的标量矩阵,而是特征图,例如:
{'gender':1, 'age': 20, 'country': 100, other features ...}
通过搜索张量流教程,我发现 Example 协议缓冲区可能适合这里,因为它基本上包含一个功能列表。但我不确定如何将其转换为 Java Tensor 对象。
如果我直接使用序列化的 Example 对象创建 Tensor,TensorFlow 运行时似乎对数据类型不满意。例如,我执行以下操作,
Tensor inputTensor = Tensor.create(example.toByteArray());
s.runner().feed(inputTensorName, inputTensor).fetch(outputTensorName).run().get(0);
我会得到一个 IllegalArgumentException:
java.lang.IllegalArgumentException: Expected serialized to be a vector, got shape: []
如果你们碰巧知道或有相同的用例,你们能否阐明我如何从这里继续前进?
谢谢!
查看您的错误消息,问题似乎在于您的模型需要一个字符串张量向量(很可能对应于一批序列化的 Example
协议缓冲区消息,可能来自 tf.parse_example
) 但是你给它提供了一个标量字符串张量。
不幸的是,在解决 issue #8531 之前,Java API 无法创建 Tensor
字符串,除了标量。一旦这个问题得到解决,事情就会变得容易。
与此同时,您可以通过构建 TensorFlow "model" 将标量字符串转换为大小为 1 的向量来解决此问题:)。这可以通过这样的方式完成:
// A TensorFlow "model" that reshapes a string scalar into a vector.
// Should be much prettier once https://github.com/tensorflow/tensorflow/issues/7149
// is resolved.
private static class Reshaper implements AutoCloseable {
Reshaper() {
this.graph = new Graph();
this.session = new Session(graph);
this.in =
this.graph.opBuilder("Placeholder", "in")
.setAttr("dtype", DataType.STRING)
.build()
.output(0);
try (Tensor shape = Tensor.create(new int[] {1})) {
Output vectorShape =
this.graph.opBuilder("Const", "vector_shape")
.setAttr("dtype", shape.dataType())
.setAttr("value", shape)
.build()
.output(0);
this.out =
this.graph.opBuilder("Reshape", "out").addInput(in).addInput(vectorShape).build().output(0);
}
}
@Override
public void close() {
this.session.close();
this.graph.close();
}
public Tensor vector(Tensor input) {
return this.session.runner().feed(this.in, input).fetch(this.out).run().get(0);
}
private final Graph graph;
private final Session session;
private final Output in;
private final Output out;
}
通过上面的内容,您可以将示例原型张量转换为向量,然后将其输入到您感兴趣的模型中,如下所示:
Tensor inputTensor = null;
try (Tensor scalar = Tensor.create(example.toByteArray())) {
inputTensor = reshaper.vector(scalar);
}
s.runner().feed(inputTensorName, inputTensor).fetch(outputTensorName).run().get(0);
有关详细信息,see this example on github
希望对您有所帮助!