I would like to add an LSTM layer before the softmax layer so that I can keep track of the context of a sequence and use it for prediction. Following is my implementation but I get every time the following error. Please help me to solve this error.
ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=2
common_model = Sequential()
common_model.add(Conv2D(32, (3, 3), input_shape=self.state_size, padding='same', activation='relu'))
common_model.add(Dropout(0.2))
common_model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
common_model.add(MaxPooling2D(pool_size=(2, 2)))
common_model.add(Flatten())
common_model.add(Dense(512, activation='relu'))
common_model.add(Dropout(0.5))
common_model.add(Dense(512, activation='relu'))
common_model.add(Dropout(0.5))
common_model.add(Dense(512, activation='relu'))
common_model.add(Dropout(0.5))
agent_model = Sequential()
agent_model.add(common_model)
agent_model.add(LSTM(512, return_sequences=False))
agent_model.add(Dense(self.action_size, activation='softmax'))
agent_model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=self.agent_learning_rate))
critic_model = Sequential()
critic_model.add(common_model)
critic_model.add(Dense(1, activation='linear'))
critic_model.compile(loss="mse", optimizer=Adam(lr=self.critic_learning_rate))
I still don't quite understand the purpose of appending LSTM after Dense, but that error can be explained:
Because in Keras, the LSTM accept the input tensor like (?, m, n) which need to have 3 dims, while the output of Dense is (?, p) which has 2 dims.
You may want to try Embedding or Reshape layer, for example:
model.add(Embedding(512, 64, input_length=512))
or
model.add(Reshape((512, 64)))
Also it is good to check some examples of using LSTM: https://github.com/keras-team/keras/tree/master/examples
Related
I have created the following neural networks:
model = keras.Sequential()
model.add(layers.Conv2D(3, (3,3), activation="relu", padding="same", input_shape=constants.GRID_SHAPE))
model.add(layers.MaxPooling2D((3,3)))
model.add(layers.Flatten())
model.add(layers.Dense(constants.NUM_ACTIONS), activation="softmax")
where constants.GRID_SHAPE is (4,12).
I get the following error:
ValueError: Input 0 of layer "conv2d" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (None, 4, 12)
How can I fix this problem?
Make sure you have a 3D input shape excluding the batch size if you plan to use the Conv2D layer. Currently you have a 2D input shape. Also make sure the activation function softmax is part of the Dense layer:
import tensorflow as tf
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(3, (3,3), activation="relu", padding="same", input_shape=(4, 12, 1)))
model.add(tf.keras.layers.MaxPooling2D((3,3)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(5, activation="softmax"))
If your input data is of the shape (samples, 4, 12), you can use data = tf.expand_dims(data, axis=-1) to add an extra dimension to your data to make it compatible with the Conv2D layer.
If you do not want to add a new dimension, you could also simply use a Conv1D layer:
import tensorflow as tf
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv1D(3, 3, activation="relu", padding="same", input_shape=(4, 12)))
model.add(tf.keras.layers.MaxPooling1D(3))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(5, activation="softmax"))
I want to use a model for classifying eight class of images. I think using convolutional layers before recurrent layers can work for my problem. But, there is a problem using recurrent layers immediately after convolutional or dense layer which causes tensorflow give following error.
Input 0 is incompatible with layer simple_rnn_1: expected ndim=3, found ndim=2
I solve this problem using Tensorflow expand_dims() function using inside a Lambda layer. It seems worked properly but, I want to be sure about my model is working right. Despite looking at relevant documentation, I couldn't understand what expand_dims() done to make the model work.
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dropout, Flatten, Dense, Lambda, SimpleRNN
from tensorflow import expand_dims
def create_model():
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(50, 50, 1), padding='same',
activation='relu'))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Lambda(lambda x: expand_dims(model.output, axis=-1)))
model.add(SimpleRNN(64, return_sequences=False))
model.add(Dense(units=8, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
return model
I want to interpret CNN output as sequential information using recurrent layers (LSTM, GRU, other recurrent models). Am I doing right using Lambda layer with expand_dims()?
The Flatten layer reduces the dimensions of the images to (Batch Length, Feature dimensions), and the recurrent neural networks expect 3 dimensions for the input instead of 2, as it needs a new dimension for the time-series inputs as in (Batch Length, Time Dimensions, Feature Dimensions)
The expand_dims simply adds an extra dimension that transforms your flattened outputs to (Batch Length, Features Dimensions, 1). This means that the RNN would now work, and it will consider the features dimensions as the time dimension for the data, thus going throw them in an orderly fashion and doing what you intended.
i have been studying Keras ConvLSTM2D: ValueError on output layer
i want to use the same code but i want to do regression ( single value ).
I dont know how to do this. And i also dont understand the use of last layers of this post code. Why is averagepolling3d used?
the code from link is
model = Sequential()
model.add(ConvLSTM2D(
filters=40,
kernel_size=(3, 3),
input_shape=(None, 135, 240, 1),
padding='same',
return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(
filters=40,
kernel_size=(3, 3),
padding='same',
return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(
filters=40,
kernel_size=(3, 3),
padding='same',
return_sequences=True))
model.add(BatchNormalization())
model.add(AveragePooling3D((1, 135, 240)))
model.add(Reshape((-1, 40)))
model.add(Dense(
units=9,
activation='sigmoid'))
model.compile(
loss='categorical_crossentropy',
optimizer='adadelta'
)
AveragePooling3D is used to reduce each frame in a sequence to a single value + to reduce the #parameters in the Dense Layer. So, the dimension becomes (None, 40 , 1 , 1 ,1 ). Then, using Reshape allows it to use for fully-connected part.
Also, as in Keras ConvLSTM2D: ValueError on output layer, AveragePooling3D is used instead of GlobalMaxPooling2D since data is 5D and Global operations leaves only (batch_size, channels) which is not desirable in your case.
I am trying to build a simple Convolutional NN with:
340 samples,
260 rows per sample
16 features per row.
I thought the order of the shape is (batch_size, steps, input_dim), which would mean (340, 16, 260) I believe.
Current code:
model = Sequential()
model.add(Conv1D(64, kernel_size=3, activation='relu', input_shape=(340, 16, 260)))
# model.add(Conv2D(64, 2, activation='relu'))
model.add(MaxPooling1D())
# model.add(Conv2D(128, 2, activation='relu'))
model.add(Conv1D(64, kernel_size=3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dense(1, activation='linear'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.summary()
model.fit(xTrain, yTrain, batch_size=16, epochs=1000)
I am getting an error:
ValueError: Input 0 is incompatible with layer conv1d_1: expected ndim=3, found ndim=4
I am very lost and believe that my shapes are off. Could someone help me?
Thank you!
As mentioned in this answer, layers in Keras, accept two arguments: input_shape and batch_input_shape. The difference is that input_shape does not contain the batch size, while batch_input_shape is the full input shape, including the batch size.
Based on this, I think the specification input_shape=(340, 16, 260) tells keras to expect a 4-dimensional input, which is not what you want. The correct argument would be batch_input_shape=(340, 16, 260).
I'm creating a model to classify if the input waverform contains rising edge of SDA of I2C line.
My input has 20000 datapoints and 100 training data.
I've initially found an answer regarding the input in here Keras 1D CNN: How to specify dimension correctly?
However, I'm getting an error in the activation function:
ValueError: Error when checking target: expected activation_1 to have 3 dimensions, but got array with shape (100, 1)
My model is:
model.add(Conv1D(filters=n_filter,
kernel_size=input_filter_length,
strides=1,
activation='relu',
input_shape=(20000,1)))
model.add(BatchNormalization())
model.add(MaxPooling1D(pool_size=4, strides=None))
model.add(Dense(1))
model.add(Activation("sigmoid"))
adam = Adam(lr=learning_rate)
model.compile(optimizer= adam, loss='binary_crossentropy', metrics=['accuracy'])
model.fit(train_data, train_label,
nb_epoch=10,
batch_size=batch_size, shuffle=True)
score = np.asarray(model.evaluate(test_new_data, test_label, batch_size=batch_size))*100.0
I can't determine the problem in here. On why the activation function expects a 3D tensor.
The problem lies in the fact that starting from keras 2.0, a Dense layer applied to a sequence will apply the layer to each time step - so given a sequence it will produce a sequence. So your Dense is actually producing a sequence of 1-element vectors and this causes your problem (as your target is not a sequence).
There are several ways on how to reduce a sequence to a vector and then apply a Dense to it:
GlobalPooling:
You may use GlobalPooling layers like GlobalAveragePooling1D or GlobalMaxPooling1D, eg.:
model.add(Conv1D(filters=n_filter,
kernel_size=input_filter_length,
strides=1,
activation='relu',
input_shape=(20000,1)))
model.add(BatchNormalization())
model.add(GlobalMaxPooling1D(pool_size=4, strides=None))
model.add(Dense(1))
model.add(Activation("sigmoid"))
Flattening:
You might colapse the whole sequence to a single vector using Flatten layer:
model.add(Conv1D(filters=n_filter,
kernel_size=input_filter_length,
strides=1,
activation='relu',
input_shape=(20000,1)))
model.add(BatchNormalization())
model.add(MaxPooling1D(pool_size=4, strides=None))
model.add(Flatten())
model.add(Dense(1))
model.add(Activation("sigmoid"))
RNN Postprocessing:
You could also add a recurrent layer on a top of your sequence and make it to return only the last output:
model.add(Conv1D(filters=n_filter,
kernel_size=input_filter_length,
strides=1,
activation='relu',
input_shape=(20000,1)))
model.add(BatchNormalization())
model.add(MaxPooling1D(pool_size=4, strides=None))
model.add(SimpleRNN(10, return_sequences=False))
model.add(Dense(1))
model.add(Activation("sigmoid"))
Conv1D has its output with 3 dimensions (and it will keep like that until the Dense layer).
Conv output: (BatchSize, Length, Filters)
For the Dense layer to output only one result, you need to add a Flatten() or Reshape((shape)) layer, to make it (BatchSize, Lenght) only.
If you call model.summary(), you will see exactly what shape each layer is outputting. You have to adjust the output to be exactly the same shape as the array you pass as the correct results. The None that appears in those shapes is the batch size and may be ignored.
About your model: I think you need more convolution layers, reducing the number of filters gradually, because condensing so much data in a single Dense layer does not usually bring good results.
About dimensions: keras layers toturial and samples