scai - 4 months ago 46

C++ Question

Suppose I have a tensor created with the Python API of Tensorflow, as follows,

`x = tf.placeholder("float", shape=[None, inputLen])`

I would like to create a tensorflow::Tensor equivalent of that in C++, so that I can run a trained graph that takes x as the input. What should I do with the first dimension of the input shape, which in C++ is of type tensorflow::TensorShape?

If I do:

`tensorflow::TensorShape inputShape;`

inputShape.AddDim(0);

inputShape.AddDim(inputLen);

it doesn't seem to work, because num_elements becomes 0, which is not the value of inputLen that I expect.

Answer

**Update**: There is now a `tensorflow::PartialTensorShape`

class that can represent shapes with unknown dimensions or an unknown rank. The value `-1`

is used to represent an unknown value (i.e. what `None`

represents in Python). It is used in the C++ shape inference code, and can be specified in a shape-typed attr or a `tf.TensorShape`

proto.

**TL;DR:** There is no equivalent in C++ because the C++ part of TensorFlow only checks shapes at runtime, when they are fully defined; whereas the Python part checks shapes at graph-construction time, when they might not be fully defined.

There is no equivalent of `tf.Dimension(None)`

(i.e., an unknown dimension) in the C++ `tensorflow::TensorShape`

class. This is because the (C++) `tensorflow::TensorShape`

class describes the shape of a (C++) `tensorflow::Tensor`

, which represents a **concrete** value for a tensor, and therefore must have a fully defined shape. The Python `tf.Tensor`

class represents a **symbolic** tensor—representing the output of an operation that has yet to be run—and so it can have a shape that is unknown in one or more dimensions.

If you are using the C++ API to feed a placeholder, you should simply create a new `tensorflow::Tensor`

with a fully defined shape for each different value that you feed to the placeholder (in a `Session::Run()`

call). Note however that the C++ API does not check shapes of placeholders, so you should manually ensure that the shape matches the expected shape for the placeholder.

If you are building a graph using the C++ API, and you want to *define* a placeholder with an unknown size in one or more dimensions, you should define a placeholder node with its `shape`

attr set to `tensorflow::TensorShape({})`

. Although this is equivalent to a scalar, for historical reasons this is treated as the shape being completely unconstrained.