Incompatible shape with the expected and input shapes in AI model creation - python

I'm pretty new to this AI model creation and I'm trying to create a activity recognition model using heatmaps using this reference Human activity recognition model
In the above link they're doing activity recognition by providing some video feed, the videos have been sliced into frames and training the model here in reference link.
But in my case I'm providing the sliced frames(images) directly for the training.
The problem is that when I'm providing my dataset for AI model creation, the input is not matching with expected input.
I'm getting this error
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 4, 8, 8, 3), found shape=(4, 8, 8, 3)
Here is my code
seed_constant = 27
np.random.seed(seed_constant)
random.seed(seed_constant)
tf.random.set_seed(seed_constant)
CLASSES_LIST = ["Forward", "Backward"]
SEQUENCE_LENGTH = 4
IMAGE_HEIGHT = 8
IMAGE_WIDTH = 8
DATASET_DIR = r"D:\ppl_count.tar (1)\ppl_count\ppl_count\datasets\ir\dataset_test"
Input = (IMAGE_WIDTH, IMAGE_HEIGHT)
def create_dataset():
"""
This function will extract the data of the selected classes and create the required dataset.
Returns:
features: A list containing the extracted frames of the videos.
labels: A list containing the indexes of the classes associated with the videos.
video_files_paths: A list containing the paths of the videos in the disk.
"""
images_dire = r"D:\ppl_count.tar (1)\ppl_count\ppl_count\datasets\ir\test_sample"
dataset_files = create_dataset_files(images_dir=images_dire, datasets_dir=DATASET_DIR,
split_size=100,
num_threads=1,
resize=Input, normalize=True)
return dataset_files
create_dataset()
data1 = numpy.load(r"D:\ppl_count.tar
(1)\ppl_count\ppl_count\datasets\ir\dataset_test\dataset0.npz",
allow_pickle=True)
features_ = data1.f.data
labels_ = data1.f.labels
one_hot_encoded_labels = to_categorical(labels_)
# splits data into train and test sets
features_train, features_test, labels_train, labels_test = train_test_split(features_,
one_hot_encoded_labels,
test_size=0.25,
shuffle=True,
random_state=seed_constant)
print("dataset_creation_success")
def create_convlstm_model():
"""
This function will construct the required convlstm model.
Returns:
model: It is the required constructed convlstm model.
"""
# We will use a Sequential model for model construction
model = Sequential()
# Define the Model Architecture.
# #######################################################################################################################
model.add(ConvLSTM2D(filters=4, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=(SEQUENCE_LENGTH,
IMAGE_HEIGHT, IMAGE_WIDTH, 3)))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 1, 1), padding='same', data_format='channels_last'))
model.add(TimeDistributed(Dropout(0.2)))
print(f'1_works')
model.add(ConvLSTM2D(filters=8, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=(SEQUENCE_LENGTH,
IMAGE_HEIGHT, IMAGE_WIDTH, 3)))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 1, 1), padding='same', data_format='channels_last'))
model.add(TimeDistributed(Dropout(0.2)))
print(f'2_works')
model.add(ConvLSTM2D(filters=14, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=(SEQUENCE_LENGTH,
IMAGE_HEIGHT, IMAGE_WIDTH, 3)))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 1, 1), padding='same', data_format='channels_last'))
model.add(TimeDistributed(Dropout(0.2)))
print(f'3_works')
model.add(ConvLSTM2D(filters=16, kernel_size=(3, 3), activation='tanh', padding='same', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=(SEQUENCE_LENGTH,
IMAGE_HEIGHT, IMAGE_WIDTH, 3)))
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 1, 1), padding='same', data_format='channels_last'))
model.add(TimeDistributed(Dropout(0.2)))
model.add(Flatten())
model.add(Dense(len(CLASSES_LIST), activation="softmax"))
# #######################################################################################################################
# Display the models summary.
model.summary()
# Return the constructed convlstm model.
return model
convlstm_model = create_convlstm_model()
# Display the success message.
print("Model Created Successfully!")
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10, mode='min',
restore_best_weights=True)
# Compile the model and specify loss function, optimizer and metrics values to the model
convlstm_model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=
["accuracy"])
# Start training the model.
convlstm_model_training_history = convlstm_model.fit(x=features_train, y=labels_train,
epochs=50, batch_size=4,
shuffle=True, validation_split=0.2,
callbacks=[early_stopping_callback])
**please do ignore some indentations as it's very difficult to post with indentations and provide any solution/reference where I can get answer from. **

tf.keras.layers.ConvLSTM2D expects input of shape 5D but you are giving 4D input.
I could reproduce your issue
import tensorflow as tf
SEQUENCE_LENGTH = 4
IMAGE_HEIGHT = 8
IMAGE_WIDTH = 8
input_shape = (SEQUENCE_LENGTH, IMAGE_HEIGHT, IMAGE_WIDTH,3)
x = tf.random.normal(input_shape)
y = tf.keras.layers.ConvLSTM2D(filters=4, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=input_shape)(x)
print(y.shape)
Output
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-6a18c66320ed> in <module>()
5 x = tf.random.normal(input_shape)
6 y = tf.keras.layers.ConvLSTM2D(filters=4, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
----> 7 recurrent_dropout=0.2, return_sequences=True, input_shape=input_shape)(x)
8 print(y.shape)
2 frames
/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py in assert_input_compatibility(input_spec, inputs, layer_name)
212 ndim = shape.rank
213 if ndim != spec.ndim:
--> 214 raise ValueError(f'Input {input_index} of layer "{layer_name}" '
215 'is incompatible with the layer: '
216 f'expected ndim={spec.ndim}, found ndim={ndim}. '
ValueError: Input 0 of layer "conv_lstm2d_4" is incompatible with the layer: expected ndim=5, found ndim=4. Full shape received: (4, 8, 8, 3)
Working sample code
import tensorflow as tf
SEQUENCE_LENGTH = 4
IMAGE_HEIGHT = 8
IMAGE_WIDTH = 8
input_shape = (16,SEQUENCE_LENGTH, IMAGE_HEIGHT, IMAGE_WIDTH,3)
x = tf.random.normal(input_shape)
y = tf.keras.layers.ConvLSTM2D(filters=4, kernel_size=(3, 3), activation='tanh', data_format="channels_last",
recurrent_dropout=0.2, return_sequences=True, input_shape=input_shape)(x)
print(y.shape)
Output
(16, 4, 6, 6, 4)

Related

Keras Error: Data cardinality is ambiguous

I am trying the following snippet on 64 images of size 28,28,1, but it throws
ValueError: Data cardinality is ambiguous
despite I think the dimensions of the tensors being correct.
loss = model_net.train_on_batch(Batch_X, Batch_Y)
print(type(Batch_X)):<class 'list'>
print(type(Batch_X[1][0])):<class 'numpy.ndarray'>
print(type(Batch_Y)):<class 'numpy.ndarray'>
print(np.shape(Batch_X)):(2, 64, 28, 28, 1)
print(np.shape(Batch_Y)):(64,)
Model is
input_shape=(28,28,1)
left_input = Input(input_shape)
right_input = Input(input_shape)
model = Sequential([
Conv2D(filters=64, kernel_size=(3, 3), activation='relu',input_shape=(28, 28, 1)),
MaxPool2D(pool_size=(2, 2), strides=2),
Conv2D(filters=64, kernel_size=(3, 3), activation='relu'),
MaxPool2D(pool_size=(2, 2), strides=2),
Flatten(),
Dense(units=4096, activation='sigmoid')])
model.summary()
encoded_l = model(left_input)
encoded_r = model(right_input)
subtracted = keras.layers.Subtract()([encoded_l, encoded_r])
prediction = Dense(1, activation='sigmoid')(subtracted)
model_net = Model(inputs=[left_input, right_input], outputs=prediction)
optimizer= Adam(learning_rate=0.0006)
model_net.compile(loss='binary_crossentropy', optimizer=optimizer)
plot_model(model_net, show_shapes=True, show_layer_names=True)
In the above you can see the model takes in 2 images simultaneously for forward pass; thus every element in Batch_X comprises of 2 matrixes. Any suggestions where I am likely making a mistake.

Keras model ValueError: Can not squeeze dim[1], expected a dimension of 1, got 90

My current model is:
# from tensorflow.keras.layers import InputLayer
model_training = Sequential()
# input_layer = keras.Input(shape=(300,1))
model_training.add(InputLayer(input_shape=(300,1)))
model_training.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='tanh'))
model_training.add(Dropout(0.2))
model_training.add(MaxPooling1D(pool_size=3))
model_training.add(Dropout(0.2))
model_training.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='tanh'))
model_training.add(Dropout(0.2))
model_training.add(MaxPooling1D(pool_size=3))
# model_training.add(Dropout(0.2))
# model_training.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='tanh'))
# model_training.add(Dropout(0.2))
# model_training.add(MaxPooling1D(pool_size=3))
# model_training.add(Dropout(0.2))
# model_training.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='tanh'))
# model_training.add(Dropout(0.2))
# model_training.add(MaxPooling1D(pool_size=3))
# model_training.add(Dropout(0.2))
#model.add(Dropout(0.2))
model_training.add(Flatten())
model_training.add(Dense(90))
model_training.add(Activation('sigmoid'))
model_training.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model_training.summary())
My fit function:
model_training.fit(train_data, train_labels, validation_data=(test_data, test_labels), batch_size=32, epochs=15)
I get this error when I run this:
ValueError: Can not squeeze dim[1], expected a dimension of 1, got 90 for '{{node Squeeze}} = Squeeze[T=DT_FLOAT, squeeze_dims=[-1]](remove_squeezable_dimensions/Squeeze)' with input shapes: [?,90].
Any idea?
my output layer has 90 as there are 90 classes in total to give a prediction on.
The train and labels are shaped as follows:
(7769, 300, 1)
(7769, 90, 1)
I can't figure out this issue. Any help is appreciated!
Partial model summary:
Squeeze your labels before training:
train_labels = tf.squeeze(train_labels, axis=-1)
It seems like the shape of your labels is the problem. The model will output a shape of (batch, 90), but you are providing (batch, 90, 1). Keras is unable to squeeze dimension 1 because it has a length of 90 and not 1.

Loss is NaN on image classification task

I'm trying to train a basic CNN on the image dataset that contains faces of celebrities with the class assigned corresponding to each person. Given that there are about 10,000 classes I used sparse_categorical_crossentropy rather than one-hot encoding the classes, however as soon as the network starts training the loss is stuck at one number and after several batches is goes to NaN I tried different scaling of the images and a smaller network but with no luck. Any clues on what might be causing the NaN?
Function that generates batches:
def Generator(data, label, batch_size):
url = "../input/celeba-dataset/img_align_celeba/img_align_celeba/"
INPUT_SHAPE = (109, 109)
i = 0
while True:
image_batch = [ ]
label_batch = [ ]
for b in range(batch_size):
if i == len(data):
i = 0
data, label = shuffle(data, label)
sample = data[i]
label_batch.append(label[i])
i += 1
image = cv2.resize(cv2.imread(url + sample), INPUT_SHAPE)
image_batch.append((image.astype(float)) / 255)
yield (np.array(image_batch), np.array(label_batch))
The model:
class CNN():
def __init__(self, train, val, y_train, y_val, batch_size):
## Load the batch generator
self.train_batch_gen = Generator(train, y_train, batch_size)
self.val_batch_gen = Generator(val, y_val, batch_size)
self.input_shape = (109, 109, 3)
self.num_classes = len(np.unique(y_train))
self.len_train = len(train)
self.len_val = len(val)
self.batch_size = batch_size
self.model = self.buildModel()
def buildModel(self):
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding="same", input_shape=self.input_shape))
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same", input_shape=self.input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="same"))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding="same"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(96, (3, 3), activation='relu', padding="same"))
model.add(layers.Conv2D(192, (3, 3), activation='relu', padding="same"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding="same"))
model.add(layers.Conv2D(256, (3, 3), activation='relu', padding="same"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(160, (3, 3), activation='relu', padding="same"))
model.add(layers.Conv2D(320, (3, 3), activation='relu', padding="same"))
model.add(layers.AveragePooling2D(pool_size=(4, 4)))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='tanh'))
model.add(layers.Dropout(rate=0.1))
model.add(layers.Dense(self.num_classes, activation = "softmax")) #Classification layer or output layer
opt = tf.keras.optimizers.Adam(learning_rate=0.00001)
model.compile(optimizer=opt, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
return model
def trainModel(self, epochs):
self.model.fit_generator(generator=self.train_batch_gen,
steps_per_epoch = int(self.len_train // self.batch_size),
epochs=epochs,
validation_data = self.val_batch_gen,
validation_steps = int(self.len_val // self.batch_size))
In my case, I used sparse_categorical_crossentropy with labels numbered from [1,2,3] (3 classes). In this case it produced NaNs from the start.
When I changed the labels from [1,2,3] to [0,1,2] the problem has disappeared.
Not sure why you are seeing those nans. I suspect it has something to do with your tanh activation on your dense layer. I would replace it with relu. I also suggest using more neurons on this dense layer cause 128 is probably small for a 10000 output.
If i were you, i would also try a pre-trained model and/or Siamese networks.
This looks like Exploding Gradients problem. I would recommend you to check how the weights and gradients are varying. See this: https://github.com/keras-team/keras/issues/2226
Check https://www.dlology.com/blog/how-to-deal-with-vanishingexploding-gradients-in-keras/ on how to spot exploding gradient problem and solutions to it. Also try out Xavier initialization in your dense layers to prevent exploding gradients.

Managing Reshape correctly to build RNN from a previous CNN

I am currently trying to build a CRNN with Keras. When I try to reshape the input size, I had some trouble finding the correct dimension for my LSTM. After some debugging, I found a field in my model object called output_shape whose value was (3,1,244) and I tried to pass it as a 2D array with (3,224). Everything worked fine, but did I do correctly? What is the math behind this and what can I do next time to discover this size without debugging?
def CRNN(blockSize, blockCount, inputShape, trainGen, testGen, epochs):
model = Sequential()
# Conv Layer
channels = 32
for i in range(blockCount):
for j in range(blockSize):
if (i, j) == (0, 0):
conv = Conv2D(channels, kernel_size=(5, 5),
input_shape=inputShape, padding='same')
else:
conv = Conv2D(channels, kernel_size=(5, 5), padding='same')
model.add(conv)
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.15))
if j == blockSize - 2:
channels += 32
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.15))
# Feature aggregation across time
model.add(Reshape((3, 224)))
# LSTM layer
model.add(Bidirectional(LSTM(200), merge_mode='ave'))
model.add(Dropout(0.5))
# Linear classifier
model.add(Dense(4, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy']) # F1?
model.fit_generator(trainGen,
validation_data=testGen, steps_per_epoch = trainGen.x.size // 20,
validation_steps = testGen.x.size // 20,
epochs=epochs, verbose=1)
return model
# Function call
model = CRNN(4, 6, (140, 33, 1), trainGen, testGen, 1)

ResourceExhaustedError when allocating tensor of shape [] and type float Keras

My input is 299,299,3
My graphics card is 1070 (8 gigs of ram)
Other Specs: Python 3.6, Keras 2.xx, Tensorflow-backend(1.4), Windows 7
Even batch size of 1 isn't working.
I feel like my card should handle a batch of size one --
Here is my code:
def full_model():
#model layers
input_img = Input(shape=(299, 299, 3))
tower_1 = Conv2D(64, (1, 1,), padding='same', activation='relu')(input_img)
tower_1 = Conv2D(64, (3, 3), padding='same', activation='relu')(tower_1)
tower_2 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)
tower_2 = Conv2D(64, (5, 5), padding='same', activation='relu')(tower_2)
concatenated_layer = keras.layers.concatenate([tower_1, tower_2], axis=3)
bottleneck = MaxPooling2D((2, 2), strides=(2, 2), padding='same')(concatenated_layer)
flatten = Flatten()(bottleneck)
dense_1 = Dense(500, activation = 'relu')(flatten)
predictions = Dense(12, activation = 'softmax')(dense_1)
model = Model(inputs= input_img, output = predictions)
SGD =keras.optimizers.SGD(lr=0.1, momentum=0.0, decay=0.0, nesterov=False)
model.compile(optimizer=SGD,
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
hdf5_path =r'C:\Users\Moondra\Desktop\Keras Applications\training.hdf5'
model = full_model()
def run_model( hdf5_path,
epochs = 10,
steps_per_epoch =8,
classes =12,
batch_size =1, model= model ):
for i in range(epochs):
batches = loading_hdf5_files.load_batches(batch_size =1,
hdf5_path=hdf5_path ,
classes = classes)
for i in range(steps_per_epoch):
x,y = next(batches)
#plt.imshow(x[0])
#plt.show()
x = (x/255).astype('float32')
print(x.shape)
data =model.train_on_batch(x,y)
print('loss : {:.5}, accuracy : {:.2%}'.format(*data))
return model
I can't seem to handle even a batch of size one.
Here is the last part of the error:
ResourceExhaustedError (see above for traceback): OOM when allocating tensor of shape [] and type float
[[Node: conv2d_4/random_uniform/sub = Const[dtype=DT_FLOAT, value=Tensor<type: float shape: [] values: 0.0866025388>, _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
It turns out I have way too many parameters.
After running print(model.summary()), I had a billion plus parameters.
I increased size of MaxPooling and no more problems.

Categories