Error when checking model target: expected dense_3

2019-07-29 16:37发布

问题:

I'm trying to train this Convolutional Neural Network but can't figure out what the issue is with my last layer.

model = Sequential()
model.add(Conv1D(50, kernel_size=(1),
                 activation='relu',
                 input_dim=50))
model.add(Dense(32))
model.add(Dense(1))
model.summary()
model.compile(loss=keras.losses.mean_squared_error,
              optimizer=keras.optimizers.adam())

model.fit(X_train, y_train,
          batch_size=940,
          epochs=10,
          verbose=1,
          validation_data=(X_test, y_test))

Model:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_26 (Conv1D)           (None, None, 50)          2550      
_________________________________________________________________
dense_38 (Dense)             (None, None, 32)          1632      
_________________________________________________________________
dense_39 (Dense)             (None, None, 1)           33        
=================================================================
Total params: 4,215.0
Trainable params: 4,215
Non-trainable params: 0.0
_________________________________________________________________

I always get the following error message:

ValueError: Error when checking model target: expected dense_39 to have 3 dimensions, but got array with shape (940, 1)

I suspect the issue is that for the last layer I got only one output node, so the output dimensions are reduced to two.

回答1:

A 1D convolution expects inputs in the form (BatchSize,length,channels).
Keras would report that as (None,length,channels).

So, you need to pass the input_shape accordingly. If you have only one channel in your data, you need to define it as:

model.add(Conv1D(50, kernel_size=(1),
             activation='relu',
             input_shape=(50,1)))

And make sure that your X_train also follows that, being shaped like (NumberOfSamples, 50, 1).

This will output tensors in shape (NumberOfSamples,50,50) - The first 50 is from the length that came in, the second is from the 50 filters defined in the layer.

After that, dense layers often expect flattened data, not 2D data.

You can use them as you did, but they will keep the extra dimensions, and that doesn't seem to be your purpose.

If you want only one class at the end (I'm guessing that), you need to flatten your data before using the Dense layers:

model.add(Flatten()) #this will transform (None, 50,50) into (None,2500)
model.add(Dense(32))
model.add(Dense(1))

Then your output will indeed have shape (None,1), which matches your Y_train (940,1)