Sunny J
Sunny J

Reputation: 47

Tensorflow Keras ValueError on input shape

I am doing a simple Conv1D using TensorFlow Keras to try out a time-series dataset.

Data:

train_df = dff[:177] #get train data
tdf = train_df.shape #get shape = (177,4)
test = tf.convert_to_tensor(train_df)

Model:

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv1D(filters=32,
                           kernel_size=1,
                           strides=1,
                           padding="causal",
                           activation="relu",
                           input_shape=tdf),
    tf.keras.layers.MaxPooling1D(pool_size=2, strides=1, padding="valid")
])

lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(5e-4,
                                                             decay_steps=1000000,
                                                             decay_rate=0.98,
                                                             staircase=False)
model.compile(loss=tf.keras.losses.MeanSquaredError(),
              optimizer=tf.keras.optimizers.SGD(learning_rate=lr_schedule, momentum=0.8),
              metrics=['mae'])
model.summary()

Summary:

Model: "sequential_13"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_16 (Conv1D)           (None, 177, 32)           160       
_________________________________________________________________
max_pooling1d_8 (MaxPooling1 (None, 176, 32)           0         
=================================================================
Total params: 160
Trainable params: 160
Non-trainable params: 0

Fit:

trainedModel = model.fit(test,
                    epochs=100,
                    steps_per_epoch=1,
                    verbose=1)

Error raised @ Fit:

ValueError: Input 0 of layer sequential_13 is incompatible with the layer: : expected min_ndim=3, found ndim=2. Full shape received: (2, 1)

From the various SO, it was said that this is due to the input data shape. So I tried a recommendation in a SO to reshape the my data and re-input it

Reshape:

X_train=np.reshape(test,(test.shape[0], test.shape[1],1))

Error raised @ Fit after reshaping:

ValueError: Input 0 of layer sequential_14 is incompatible with the layer: expected axis -1 of input shape to have value 4 but received input with shape (177, 4, 1)

I am at a loss here. What is the way to tackle this?

Upvotes: 1

Views: 5029

Answers (1)

Abhishek Prajapat
Abhishek Prajapat

Reputation: 1888

Current Parametric values:

  1. tdf = (177,4) My assumption - "You have 4 features for 177 training samples".

The Reason of current Error - The model assumes that each sample is of shape (177,4) but when you try to pass it to the model the error comes which is

ValueError: Input 0 of layer sequential_13 is incompatible with the layer: :
expected min_ndim=3, found ndim=2. Full shape received: (2, 1)

This error says that the model expected the input to have a 3D dimension which in this case is that model wants a batch size. Say a batch of 16 images of height=177 and width=4. (Although you don't have images but model expects this cause of how you specified your input shape). That means the input should have a shape - (batch_size, 177, 4).

This could be solved by passing a parameter batch_size=1 in the model.fit. As below (Without reshaping the data)

trainedModel = model.fit(data,
                    epochs=100,
                    steps_per_epoch=1,
                    batch_size=16,
                    verbose=1)

But this will give another error which is as below

ValueError: Input 0 of layer sequential_1 is incompatible with the layer: : 
expected min_ndim=3, found ndim=2. Full shape received: (None, 4)

Now this error mean that the input passed to the model had some batch_size represented by None and a feature vector of shape 4 but the model expects the input to have a shape of (batch_size, height, width). Here batch_size is expected by all the models but the rest 2 are specified by us while defining the input shape. We have defined this here:

tf.keras.layers.Conv1D(filters=32,
                           kernel_size=1,
                           strides=1,
                           padding="causal",
                           activation="relu",
                           input_shape=tdf), # Here We save input_shape = (177,4)

As you can see the input_shape has been defined as height=177, width=4. (I used height and width for easier explanation otherwise there is no height/width only the dimension number). BUT, we wanted the model to take input of 4 features. So, now we have to change this to below:

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv1D(filters=32,
                           kernel_size=1,
                           strides=1,
                           padding="causal",
                           activation="relu",
                           input_shape=(4,)),
    tf.keras.layers.MaxPooling1D(pool_size=2, strides=1, padding="valid")
])

But now when you try to run this you will get another error as below:

ValueError: Input 0 of layer conv1d_10 is incompatible with the layer: : 
expected min_ndim=3, found ndim=2. Full shape received: (None, 4)

The thing to note is the error arise from the Conv1D and this is cause this layer expects the input in 3D including the batch_size but we never specify the batch_size while creating the model the parameter input_shape should have a value like this input_shape = (dim1, dim2) but in case we only have 4 features and hence only dim1 and not dim2. In this case we will reshape our input to have the 4 as (4,1). By this we will have the dim1 = 4 and the dim2 = 1. And we will update our model as below:

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv1D(filters=32,
                           kernel_size=1,
                           strides=1,
                           padding="causal",
                           activation="relu",
                           input_shape=(4,1)),
    tf.keras.layers.MaxPooling1D(pool_size=2, strides=1, padding="valid")
])

Now we also reshape our inputs to have shape (177,4, 1) as below:

train_df = dff[:177]
train_df = train_df.values.reshape(177, 4, 1)
test = tf.convert_to_tensor(train_df)

Now we can use it to pass into the model.

trainedModel = model.fit(test,
                    epochs=100,
                    steps_per_epoch=1,
                    verbose=1)

Sadly this will give yet another error like below.

ValueError: No gradients provided for any variable: ['conv1d_14/kernel:0',
'conv1d_14/bias:0'].

This is cause the model don't get any Y corresponding to your input X and hence it can't compute the gradients using the loss function and hence can't train. But it can still be used to get the outputs as below:

preds = model(test)
preds.shape # Result -> TensorShape([177, 3, 32])

Upvotes: 2

Related Questions