Problems with shape of Conv1D on Keras

I have some problems with layers construction on Keras. I explain the whole problem:

  1. I have a feature matrix, with dimensions: 2023 (rows) x 65 (features);
  2. I tried to build a CNN, with Conv1D as first layer;

My code is:

def cnn_model():
    model = Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='mse', optimizer='adam', metrics=['mse', 'mae'])
    model.fit(X, Y, epochs=100, batch_size=64, verbose=0)
    model.evaluate(X, Y)
    return model

scoring = make_scorer(score_func=pearson)
# evaluate model with standardized dataset
estimation = []
estimation.append(('standardize', StandardScaler()))
estimation.append(('mlp', KerasRegressor(build_fn=cnn_model, epochs=50, batch_size=32, verbose=0)))
pipeline = Pipeline(estimation)
kfold = KFold(n_splits=10, shuffle=True, random_state=1)
results = cross_val_score(pipeline, X, Y, cv=kfold, scoring=scoring)

The problem is that, when it runs, I get the following error:

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

I really don't know why this error occurs. Probably it's just a problem with parameters passing, I'm quite new on this field. Can you tell me something more? I tried a bunch of things in order to solve this error but every time I get some new errors instead of solving. Thank you all.

Topic reshape keras convnet

Category Data Science


If we see the Keras doc Here,

Input shape
3+D tensor with shape: batch_shape + (steps, input_dim)

So, the input should be designed as Batch, Seq, Dim.
In this case we may assume a seq length of 65 and a dimension of 1.

from sklearn.datasets import make_moons, make_circles, make_classification
from tensorflow import keras
from tensorflow.keras import layers

X, Y = make_classification(n_features=65, n_redundant=0, n_informative=1, n_clusters_per_class=1)

X = X.reshape(-1,65,1) # Reshaped to Batch, Seq, Dim

model = keras.models.Sequential()
model.add(layers.Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(layers.Dropout(0.25))
model.add(layers.Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(layers.Dropout(0.25))
model.add(layers.MaxPooling1D(pool_size=2))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='mse', optimizer='adam', metrics=['mse', 'mae'])
model.fit(X, Y, epochs=100, batch_size=64, verbose=0)
model.evaluate(X, Y)

Just tried your cnn_model function and it works correctly for me.

Not sure about what your problem is, but it seems to be your X and Y. X must not have shape (2023, 65), but shape (datasize, 2023, 65). and Y should have shape (datasize, 1) as well. otherwise your network treats X as 2023 inputs of shape (None, 65) instead of treating it as n inputs of shape (None, 2023, 65).

here is my code in case you wanna run it (important part is the definition of X(ims) and Y(lab) :

import keras
from keras.layers import Conv1D, Dropout, MaxPooling1D, Flatten, Dense
import numpy as np

ims = np.random.randn(100, 2023, 65)
lab = np.random.randn(100, 1)

def cnn_model(X, Y):
    model = keras.Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.25))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='mse', optimizer='adam', metrics=['mse', 'mae'])
    print('training')
    model.fit(X, Y, epochs=10, batch_size=32, verbose=0)
    print('finished training')
    model.evaluate(X, Y)
    return model


m = cnn_model(ims, lab)
m.summary()

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.