however, I'm not sure the proper way use StdArrays or equivalent to take an existing byte[][] and turn it into a TString
@killeent , try TString.tensorOfBytes(StdArrays.ndCopyOf(byte[][]))
TFRecord
are basically just protos that coule be read/written directly. You can use these pregenerated bindings to do so
Example
, Features
and Feature
protos . I am actually looking if there is an API in tensorflow/java
that does this particular job (TFRecord)
TFRecordDataset
in tensorflow/java
was available in org.tensorflow.framework. However, it expects a Ops
param. That's why I meant "I am looking to avoid the introduction of elements/concepts related to the computation graph".
tensorflow/java
soon.
Mat
object from OpenCV
(a preprocessed image of a symbol to be "detected") and a loaded model with session and stuff. Maybe there are some open-source examples.
Mat
object to be a representation of Tensor<Float32>
and use session runner, like explained in StackOverflow answer. Am I missing something?
TFloat32
is a subtype of Tensor
so you need to make one of those. The SavedModelBundle
exposes a call entry point which executes the requested function in the model (e.g. https://github.com/tensorflow/java/blob/35b73ce43cb821e5462ffc9ece51d6528dad224d/tensorflow-core/tensorflow-core-api/src/test/java/org/tensorflow/SavedModelBundleTest.java#L131).
TFloat32
object from my image and pass it to function.call(..)
. API says I need 4 dimensional tensor. How it can be made from 2-dimensional array like image?
NDarray.slice(Indices.newaxis(), Indices.ellipse(), Indices.newaxis())
on your ndarray. Make sure the width/height order matches your model though. In gneral, if you need to do ndarray operations your best bet is usually to load it into an eager session (Ops.constantOf
) and do it there.
Hi, I have the following
val input = TString.tensorOf(Shape.of(1, 1), DataBuffers.ofObjects(title))
val runner = session.runner()
runner.feed("serving_default_text", input)
runner.fetch("StatefulPartitionedCall").run()
however, I dont know how I can make predictions in batch, I google for some hints without success. I need to made a matrix ? dataset ? I'm a little lost without too much java documentation. Or it is ok if I reuse the runner and iterate with my inputs ? Thanks
savedModel.function(“serving_default”).signature().toString()
)
{serving_default=inputs {
key: "text"
value {
name: "serving_default_text:0"
dtype: DT_STRING
tensor_shape {
dim {
size: -1
}
dim {
size: 1
}
}
}
}
outputs {
key: "dense_2"
value {
name: "StatefulPartitionedCall:0"
dtype: DT_FLOAT
tensor_shape {
dim {
size: -1
}
dim {
size: 189
}
}
}
}
method_name: "tensorflow/serving/predict"
, __saved_model_init_op=outputs {
key: "__saved_model_init_op"
value {
name: "NoOp"
tensor_shape {
unknown_rank: true
}
}
}
}
I do have some progress, thanks to this chat. My model has this signature:
Signature for "serving_default":
Method: "tensorflow/serving/predict"
Inputs:
"conv2d_input": dtype=DT_FLOAT, shape=(-1, 30, 30, 3)
Outputs:
"dense_2": dtype=DT_FLOAT, shape=(-1, 56)
I've converted image to a required Tensor, however having problems with input Shape
which should be 4-dimensional (and Image is only 3). As @rnett said, model expexts [batch, height, width, channels]
. So what do I have now is:
val image = ImageIO.read(File("./src/test/resources/tensorflow/A.png"))
Truth.assertThat(image).isNotNull()
val byte: ByteArray = (image.data.dataBuffer as DataBufferByte).data!!
Truth.assertThat(byte).isNotEmpty()
val desiredShape = Shape.of(0L, 30, 30, 3)
// FIXME: seems like image tensor is prepared badly. Try to wrap image in NdArray and then expand its dimension by 1
val imageTensor: TFloat32 = TFloat32.tensorOf(
/*Shape.of(image.height.toLong(), image.width.toLong(), 3)*/desiredShape,
NioDataBufferFactory.create(FloatBuffer.wrap(byte.map { it.toFloat() }.toFloatArray()))
)
Truth.assertThat(imageTensor).isNotNull()
val function: ConcreteFunction = model.function(Signature.DEFAULT_KEY)
val result: Tensor = function.call(imageTensor) as TFloat32
Truth.assertThat(result).isNotNull()
println("Result rank: ${result.rank()}") // 2
println(result.size()) // 0
So now I'm thinking about preparing the right shaped image tensor, using NdArray
. Am I thinking in right direction?
If you intend to pass a single image per batch, then the size of the first dimension should be 1, not 0.
On another note, there is also this endpoint that allows you to allocate a tensor of any type from a buffer of bytes, I don’t know if that would work in and simplify your case: https://github.com/tensorflow/java/blob/35b73ce43cb821e5462ffc9ece51d6528dad224d/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/Tensor.java#L180