Search code examples
pythontensorflowkerastensorflow-datasetsfunctional-api

How do you write an input layer with Tensorflow's Functional API that expects a Dataset object?


I am trying to create an Input Layer using tf.keras.Input using the type_spec argument to specify an input of DatasetSpec using Tensorflow's Functional API so that I can iterate over it later. If I try to define an input layer by specifying shape, I get error messages complaining that iterating over tf.tensor is not allowed.

X = np.random.uniform(size=(1000,75))
Y = np.random.uniform(size=(1000))

data = tf.data.Dataset.from_tensor_slices((X, Y))
data = data.batch(batch_size=100, drop_remainder=True)


input = tf.keras.Input(type_spec = tf.data.DatasetSpec.from_value(data))

I got the following error: ValueError: KerasTensor only supports TypeSpecs that have a shape field; got DatasetSpec, which does not have a shape.


Solution

  • The data object (output of tf.data) is the tuple of two item (X and Y). In order to create specification layer (keras.Input) with tf.data.DatasetSpec.from_value(data), you need to get the shape of first element.

    tf.data.DatasetSpec.from_value(data)
    
    DatasetSpec((TensorSpec(shape=(100, 75), dtype=tf.float64, name=None),
    TensorSpec(shape=(100,), dtype=tf.float64, name=None)), TensorShape([]))
    

    Here is a dummy model with your approach,

    # element_spec[0] <- shape of the first element.
    input = tf.keras.Input(
        type_spec = tf.data.DatasetSpec.from_value(data).element_spec[0]
    )
    output = tf.keras.layers.Dense(1)(input)
    model = tf.keras.Model(input, output)
    model.compile(loss='mse')
    
    model.fit(data, epochs=3)
    Epoch 1/3
    10/10 [==============================] - 0s 2ms/step - loss: 0.2506
    Epoch 2/3
    10/10 [==============================] - 0s 2ms/step - loss: 0.2441
    Epoch 3/3
    10/10 [==============================] - 0s 2ms/step - loss: 0.2378