简体   繁体   中英

keras input shape: Input incompatible with the layer

I've looked at a few similar questions but I still don't understand how to solve my problem.

I am trying to build a CNN that estimates how many particles hit a detector, based on what's essentially an oscilloscope trace of the energy released in the detector over time.

I have 100,000 events of 1024 time samples, which I split 80/20 as train/test, like so:

from sklearn.model_selection import train_test_split
train_to_test_ratio=0.8 #proportion of the dataset to include in the train split

X_train,X_test,Y_train,Y_test=train_test_split(NormSignals,labels,train_size=train_to_test_ratio)

no_outputs = 14 # maximum number of particles expected

# force the labels to have 14 binary digits, one for each of the possible outputs 
Y_train=tf.one_hot(Y_train,no_outputs)
Y_test=tf.one_hot(Y_test,no_outputs)

When I try to define the input shape for the network I do so like this (full CNN code below):

# Define input to neural network (tensors of 1024 time samples x 1 amplitude per sample)
inputs = keras.Input(shape=(1024,1))

But it gives me the error: "Input 0 of layer Conv_1 is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [None, 1024, 1]"

I thought the input shape was as simple as the shape of the data arrays being passed to the network. Can someone please explain what the correct shape of my data should be?

Thank you very much in advance!

Full CNN:

from tensorflow import keras

# Following the architecture of the CNN from the image recognition lab (14/5/2020):
# Simple CNN:

class noiseLayer(keras.layers.Layer):

    def __init__(self,mean):
        super(noiseLayer, self).__init__()
        self.mean = mean

    def call(self, input):
        mean = self.mean
        return input + (np.random.poisson(mean))/mean

# Add data augmentation to produce a random flip of the data (the ECal is symmetrical)
# and add poissonian noise to all of the crystals - using large N and dividing by N normalises 
# the noise to be approximately continuous between 0 and 1

data_augmentation = keras.Sequential([
  noiseLayer(mean = 1000)
], name='DataAugm')

# Define input to neural network (tensors of 1024 time samples x 1 amplitude per sample)
inputs = keras.Input(shape=(1024,1))

#x=inputs
x = data_augmentation(inputs)

# primo blocco Convoluzionale

x = keras.layers.Conv2D(16, kernel_size=(3,3), name='Conv_1')(x)
x = keras.layers.LeakyReLU(0.1)(x)      
x = keras.layers.MaxPool2D((2,2), name='MaxPool_1')(x)

# secondo blocco Convoluzionale
x = keras.layers.Conv2D(16, kernel_size=(3,3), name='Conv_2')(x)
x = keras.layers.LeakyReLU(0.1)(x)
x = keras.layers.MaxPool2D((2,2), name='MaxPool_2')(x)

# terzo blocco convoluzionale 
x = keras.layers.Conv2D(32, kernel_size=(3,3), name='Conv_3')(x)
x = keras.layers.LeakyReLU(0.1)(x)
x = keras.layers.MaxPool2D((2,2), name='MaxPool_3')(x)

# Flatten output tensor of the last convolutional layer so it can be used as  
# input to the dense layers

x = keras.layers.Flatten(name='Flatten')(x)

# dense network: 2 dense hidden layer with 256 neurons, with ReLU activation

# Classifier
x = keras.layers.Dense(64, name='Dense_1')(x)
x = keras.layers.ReLU(name='ReLU_dense_1')(x)
#x = keras.layers.Dropout(0.2)(x)
x = keras.layers.Dense(64, name='Dense_2')(x)
x = keras.layers.ReLU(name='ReLU_dense_2')(x)

outputs = keras.layers.Dense(no_outputs, activation='softmax', name='Output')(x)

# Model definition
model = keras.Model(inputs=inputs, outputs=outputs, name='VGGlike_CNN')

# Print model summary
model.summary()

# Show model structure
keras.utils.plot_model(model, show_shapes=True)

The problem was that I was using 2D layers to try to solve a 1D problem.

Changing all the 2D layers to 1D now compiles without errors:


x = keras.layers.Conv1D(16, kernel_size=(3), name='Conv_1')(x)
x = keras.layers.LeakyReLU(0.1)(x)      
x = keras.layers.MaxPool1D((2), name='MaxPool_1')(x)

# secondo blocco Convoluzionale
x = keras.layers.Conv1D(16, kernel_size=(3), name='Conv_2')(x)
x = keras.layers.LeakyReLU(0.1)(x)
x = keras.layers.MaxPool1D((2), name='MaxPool_2')(x)

# terzo blocco convoluzionale 
x = keras.layers.Conv1D(32, kernel_size=(3), name='Conv_3')(x)
x = keras.layers.LeakyReLU(0.1)(x)
x = keras.layers.MaxPool1D((2), name='MaxPool_3')(x)

# Flatten output tensor of the last convolutional layer so it can be used as  
# input to the dense layers

x = keras.layers.Flatten(name='Flatten')(x)

# dense network: 2 dense hidden layer with 256 neurons, with ReLU activation

# Classifier
x = keras.layers.Dense(64, name='Dense_1')(x)
x = keras.layers.ReLU(name='ReLU_dense_1')(x)
#x = keras.layers.Dropout(0.2)(x)
x = keras.layers.Dense(64, name='Dense_2')(x)
x = keras.layers.ReLU(name='ReLU_dense_2')(x)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM