I have the following code snippet:
X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))
model = Sequential()
model.add(LSTM(200, activation='relu', input_shape=(X_train.shape[0], 1, X_train.shape[2]), return_sequences=False))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=100, batch_size=32)
y_pred = model.predict(X_test)
However, I get the following error:
ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4
The original shapes of X_train and X_test:
X_train: 1483, 13
X_test: 360, 13
and after reshaping they become:
X_train: 1483, 1, 13
X_test: 360, 1, 13
I know this might be a duplicate, but none of the answers online seem to work for me.
input_shape=(X_train.shape[0], 1, X_train.shape[2]) is wrong.
An LSTM should have 2D input shapes (which means 3D internal tensors).
l
- The input shape must contain (sequence_length, features_per_step).
- This means the internal shape will be (free_batch_size, sequence_length, features_per_step)
Your data then must be 3D, ok, but the input_shape should be 2D.
Now, sequence_length is absolutely necessary for a recurrent layer to work, if you have sequence_length = 1 it's totaly useless, unless you are going for stateful=True which involves much more complicated code.
Related
Here's my code:
(x_train, y_train), (x_test, y_test) = mnist.load_data()
def create_model():
model = tf.keras.models.Sequential()
model.add(Conv2D(64, (3, 3), input_shape=x_train.shape[1:], activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
return model
model = create_model()
the input data shape is (60000, 28, 28). its the keras mnist dataset.
and here's the error
ValueError: Input 0 of layer conv2d_1 is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [None, 28, 28]
An I have no idea whats wrong with it.
Input shape
4D tensor with shape: (batch, channels, rows, cols) if data_format is "channels_first" or 4D tensor with shape: (batch, rows, cols, channels) if data_format is "channels_last".
The Input shape is expected as (batch,channels,rows,cols) you have given number of images.
create a variable like image_size=(3,28,28)
and
input_shape = image_size
... This might work for you. or try
input_shape = (3,28,28)
I realized my mistake mnist data has a shape: (sample, width, height) and Conv2D layers require a shape (samples, width, height, depth), so the solution would be to add an extra dimension.
x_train = x_train[..., np.newaxis]
x_test = x_test[..., np.newaxis]
I'm trying to train a model Keras but I'm having a problem:
g = ImageDataGenerator(featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=45,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
validation_split=validation_split,
preprocessing_function=lambda x: x / 127 - 1)
g_train = g.flow(x_train, y_train,
batch_size=batch_size,
subset='training')
g_valid = g.flow(x_train, y_train,
batch_size=batch_size,
shuffle=False,
subset='validation')
history = network.fit_generator(g_train,
steps_per_epoch=len(x_train) / 32,
epochs=epochs)
ValueError: Error when checking target: expected predictions to have 4 dimensions, but got array with shape (256, 1)
Someone have any idea why? It seems much like the example in documentation to me.
x_train.shape
(50000, 32, 32, 1)
y_train.shape
(50000, 1, 1)
I'm trying to use maxpooling as a first layer using keras and I have a problem with the input and output dimensions.
print(x_train.shape)
print(y_train.shape)
(15662, 6)
(15662,)
x_train = np.reshape(x_train, (-1,15662, 6))
y_train = label_array.reshape(1, -1)
model = Sequential()
model.add(MaxPooling1D(pool_size = 2 , strides=1, input_shape = (15662,6)))
model.add(Dense(5, activation='relu'))
model.add(Flatten())
model.add(Dense(1, activation='softmax'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=
['accuracy'])
model.fit(x_train, y_train, batch_size= 32, epochs=1)
After running the model, I get the following error:
ValueError: Error when checking target: expected dense_622 (last layer)
to have shape (1,) but got array with shape (15662,)
I'm doing classification and my target is binary (0,1)
Thank you
Your target should have shape (batch_size, 1) but you are passing an array of shape (1, 15662). It seems like 15662 should be the batch size, in which case x_train should have shape (15662, 6) and y_train should have shape (15662, 1). In this case however, it doesn't make any sense to have a MaxPooling1D layer as the first layer of your model since max pooling requires a 3D input (i.e. shape (batch_size, time_steps, features)). You probably want to leave out the max pooling layer (and the Flatten layer). The following code should work:
# x_train: (15662, 6)
# y_train: (15662,)
model = Sequential()
model.add(Dense(5, activation='relu', input_shape=(6,))) # Note: don't specify the batch size in input_shape
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=
['accuracy'])
model.fit(x_train, y_train, batch_size= 32, epochs=1)
But it of course depends on what kind of data you have.
I am playing with a model which should take a 8x8 chess board as input, encoded as a 224x224 grey image, and then output a 64x13 one-hot-encoded logistic regression = probabilities of pieces on the squares.
Now, after the Convolutional layers I don't quite know, how to proceed to get a 2D-Dense layer as a result/target.
I tried adding a Dense(64,13) as a layer to my Sequential model, but I get the error "Dense` can accept only 1 positional arguments ('units',)"
Is it even possible to train for 2D-targets?
EDIT1:
Here is the relevant part of my code, simplified:
# X.shape = (10000, 224, 224, 1)
# Y.shape = (10000, 64, 13)
model = Sequential([
Conv2D(8, (3,3), activation='relu', input_shape=(224, 224, 1)),
Conv2D(8, (3,3), activation='relu'),
# some more repetitive Conv + Pooling Layers here
Flatten(),
Dense(64,13)
])
TypeError: Dense can accept only 1 positional arguments ('units',), but you passed the following positional arguments: [64, 13]
EDIT2: As Anand V. Singh suggested, I changed Dense(64, 13) to Dense(832), which works fine. Loss = mse.
Wouldn't it be better to use "sparse_categorical_crossentropy" as loss and 64x1 encoding (instead of 64x13) ?
In Dense you only pass the number of layers you expect as output, if you want (64x13) as output, put the layer dimension as Dense(832) (64x13 = 832) and then reshape later. You will also need to reshape Y so as to accurately calculate loss, which will be used for back propagation.
# X.shape = (10000, 224, 224, 1)
# Y.shape = (10000, 64, 13)
Y = Y.reshape(10000, 64*13)
model = Sequential([
Conv2D(8, (3,3), activation='relu', input_shape=(224, 224, 1)),
Conv2D(8, (3,3), activation='relu'),
# some more repetitive Conv + Pooling Layers here
Flatten(),
Dense(64*13)
])
That should get the job done, if it doesn't post where it fails and we can proceed further.
A Reshape layer allows you to control the output shape.
Flatten(),
Dense(64*13),
Reshape((64,13))#2D
I'm training an CNN with LSTM, where I use TimeDistributed but apparently it wants an extra dimension for the data. I don't know how to add it.
My thought is that the problem is in ImageGenerator, but I don't know how to reshape images generated from it.
cnn_model = Sequential()
cnn_model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(128,128,3)))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))
cnn_model.add(Conv2D(32, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))
cnn_model.add(Conv2D(64, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))
cnn_model.add(Conv2D(128, (3, 3), activation='relu'))
cnn_model.add(MaxPooling2D(pool_size=(2, 2)))
cnn_model.add(Flatten())
model = Sequential()
model.add(TimeDistributed(cnn_model, input_shape=(16, 128, 128,3)))
model.add(LSTM(128, return_sequences=True, dropout=0.5))
# model.add(Dropout(0.2)) #added
model.add(Dense(4, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
batch_size = 16
train_datagen = ImageDataGenerator(rescale=1. / 255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'train/', # this is the target directory
target_size=(128,128),
batch_size=batch_size,
class_mode='categorical',
shuffle=True,
classes=['class_0', 'class_1','class_2','class_3'])
validation_generator = test_datagen.flow_from_directory(
'test/',
target_size=(128,128),
batch_size=batch_size,
class_mode='categorical',
shuffle=True,
classes=['class_0', 'class_1','class_2','class_3'])
model.fit_generator(
train_generator,
steps_per_epoch=47549 // batch_size,
epochs=5,
validation_data=validation_generator,
validation_steps=5444 // batch_size)
But I'm getting the following error message
ValueError: Error when checking input: expected time_distributed_136_input to have 5 dimensions, but got array with shape (16, 128, 128, 3)
Data folder is as follows:
-- train
-- class 0
-- vid 1
-- frame1.jpg
-- frame2.jpg
-- frame3.jpg
-- class 1
-- frame1.jpg
-- frame2.jpg
-- frame3.jpg
-- class 2
-- class 3
-- test
(same as train)
Thanks for any help.
You're fogetting the first dimension of every tensor, which is the batch size. You don't define a batch size unless it's absolutely necessary, thus the input shapes don't consider it.
When you defined input_shape=(16,128,128,3), this means that your data must have five dimensions: (examples, 16, 128, 128, 3)
And the examples dimension is missing in your data.
If you say they're movies, you should have data like (movies, frames, height, width, channels), probably. Then this would be accepted by input_shape=(frames, height, width, channels).
After several trials, I ended up using the same code, but with a tweaked version of the Keras "ImageDataGenerator" Class to add an extra dimension to the data, so that it becomes 5D.
(This is also valid for the use of Conv3D)
For anyone who face the same problem, you can find my tweaked version of the ImageDataGenerator class here.
It's the same as the main Keras ImageDataGenerator but I added an option to take more than one image/frame on each iteration. This is by changing the parameter frames_per_step to specify the number of frames/images you want to include in each iteration.
So here's how to use it:
from tweaked_ImageGenerator_v2 import ImageDataGenerator
datagen = ImageDataGenerator()
train_data=datagen.flow_from_directory('path/to/data', target_size=(x, y), batch_size=32, frames_per_step=4)
I think your problem is with your model. You define the input shape of your TimeDistributed in your model as input_shape=(16, 128, 128,3) which I guess it should be input_shape=(128, 128,3).
change this line :
model.add(TimeDistributed(cnn_model, input_shape=(16, 128, 128,3)))
to:
model.add(TimeDistributed(cnn_model, input_shape=(128, 128,3)))
And I hope it will work.