Pedicting from a conv2d model says the image must be 4d too - python

This is the model I've created:
model.add(Conv2D(64, (5,5), input_shape = (28, 28, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (5, 5)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
# added layers
model.add(Dense(10))
model.add(Activation('softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(X, y, batch_size=256, epochs=25, validation_split=0.3)
But loading an image for prediction as such:
test_image = np.array(img)
test_image = test_image.astype('float32')
test_image /= 255
# image.shape is 28, 28, 3
print((model.predict(test_image)))
results in the following error:
ValueError: Input 0 of layer sequential_11 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: (None, 28, 3)
X.shape is (2163, 28, 28, 3) where 2163 is the number of pictures of 28x28 pixels.

The model expects an input with 4 dimensions. This means that you have to reshape your image with .reshape(n_images, 28, 28,3 ). Now you have added an extra dimension without changing the data . Basically, you need to reshape your data to (n_images, x_shape, y_shape, channels). Try it, Make sure the shape of your input layer is 28,28,3

You need a batch dimension, because Keras is used to that input shape. I suggest you use np.expand_dims:
test_image = np.array(img).astype('float32')
test_image = np.expand_dims(test_image, axis=0)/255
test_image = tf.image.resize_with_pad(test_image, 28, 28)
print((model.predict(test_image)))

Related

Invalid input shapes for a CNN

This is my first ML project done without any tutorials so apologies if this is a silly question.
Anyways, I'm making a CNN classifier that simply puts images in 1 of 2 categories (slouched or straight back)
I can't seem to get the input images used for prediction to match the dimensions that the model accepts. It is supposed to input 100x100 grayscale images. It keeps on returning this error:
WARNING:tensorflow:Model was constructed with shape (None, 100, 100, 1) for input KerasTensor(type_spec=TensorSpec(shape=(None, 100, 100, 1), dtype=tf.float32, name='reshape_input'), name='reshape_input', description="created by layer 'reshape_input'"), but it was called on an input with incompatible shape (None, 100).
I have tried various methods of resizing and reshaping and gray scaling (even though it is not in the code snippet), but I can't find something that works*
Here are the relevant bits of code:
print(slouchClassifier.predict(cv2.cvtColor(cv2.resize(frame, (100,100)), cv2.COLOR_BGR2GRAY)))
def predict(self, image):
return self.model.predict(image)
def trainModel(self, training, epochs = 1):
x = keras.utils.image_dataset_from_directory(
training,
labels='inferred',
label_mode='categorical',
class_names=None,
color_mode='grayscale',
batch_size=32,
image_size=(100, 100),
)
self.model.fit(x, batch_size= self.batchSize, verbose = 2, epochs = epochs) #Verbose = status updates on training
def createModel(self):
#Model
model = Sequential()
model.add(Reshape((100,100,1)))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.1))
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dense(2))
model.add(Activation('softmax'))
# initiate RMSprop optimizer
opt = keras.optimizers.RMSprop(learning_rate=0.0001)
# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
return model
I hope this is enough information for you! Let me know if you need more information about the code.
Thanks in advance :)
tensorflow:Model was constructed with shape (None, 100, 100, 1)
Your model expects an input shape of (100, 100, 1). However, you used this to prepare the input:
slouchClassifier.predict(cv2.cvtColor(cv2.resize(frame, (100,100)), cv2.COLOR_BGR2GRAY))
cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gets rid of the channel dimension entirely, resulting in an image of shape (100, 100). You need to add the channel dimension back. One way is np.expand_dims(img, -1).
For example,
img = cv2.cvtColor(cv2.resize(frame, (100, 100)), cv2.COLOR_BGR2GRAY))
img = np.expand_dims(img, -1)
pred = slouchClassifier.predict(img)

How do I choose the correct input shape to my Dense Layer?

I am working on a dataset with following input shapes of X and Y
>>> print(X_train.shape, Y_train.shape)
(211968, 1024, 2) (211968, 24)
Here's my simple model with summary and the error:
batch_size = 128
hidden_units = 256
dropout = 0.45
model = Sequential()
model.add(Dense(hidden_units,input_shape=(1024,2)))
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(hidden_units))
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(24))
model.add(Activation('softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=30, batch_size=batch_size)
ValueError: Shapes (128, 24) and (128, 1024, 24) are incompatible
The input to Dense Layer must be one dimensional vector. So a Flatten() operation before the Dense Layer did the trick.

Input a 4 channel RGB-D Image into LSTM

I have read a sequence of images (frames) into a numpy array with shape (9135, 200, 200, 4) where 9135 is the sample size, 200 is height and width in 4 channel (R-G-B-Depth) images.
I have a sequential model with an LSTM layer:
x_train=np.reshape(x_train,(x_train.shape[0],x_train.shape[1],x_train.shape[2],x_train.shape[3],1))
#(9135, 200, 200, 4, 1)
x_val=np.reshape(x_val,(x_val.shape[0],x_val.shape[1],x_val.shape[2],x_val.shape[3],1))
#(3046, 200, 200, 4, 1)
model = Sequential()
model.add(TimeDistributed(Conv2D(64, (3,3), activation='relu'), input_shape=(200, 200, 4)))
model.add(TimeDistributed(Conv2D(64, (3,3), activation='relu')))
model.add(TimeDistributed(GlobalAveragePooling2D()))
model.add(LSTM(1024, activation='relu', return_sequences=False))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(.5))
model.add(Dense(10, activation='sigmoid'))
model.compile('adam', loss='categorical_crossentropy')
model.summary()
history = model.fit(x_train, y_train, epochs=epochs,batch_size=batch_size,verbose=verbose, validation_data=(x_val, y_val))
but there is an error in the result:
ValueError: Input 0 of layer conv2d is incompatible with the layer: :
expected min_ndim=4, found ndim=3. Full shape received: [None, 200, 4]
What is the suggested way to input a 4 channel image into an LSTM layer in Keras?
PS: Εach class has different frames so I do not know how to put unstable timestep
You need to reshape
x_train=np.reshape(x_train,(x_train.shape[0],1,x_train.shape[1],x_train.shape[2],x_train.shape[3]))
#(9135,1 200, 200,4)
x_val=np.reshape(x_val,(x_val.shape[0],1,x_val.shape[1],x_val.shape[2],x_val.shape[3]))
#(3046,1 200, 200,4)
and change the input_shape of model to input_shape=(None,200, 200, 4)))

I am receiving an error with my resizing / input array for a ConvLSTM model

I have a data set with images of daily precipitation maps. I am trying to build a Precipitation Nowcasting model using ConvLSTM2D.
Please help me figure out how I can change the array’s shape to work.
Using this as a reference: https://github.com/wqxu/ConvLSTM/blob/master/radar_forecast.py
Please help me with this error:
Error when checking input: expected conv_lst_m2d_167_input to have 5 dimensions, but got array with shape (1785, 400, 320, 3)
If I add another dimension to the reshape array of X_Train:
X_Train = np.array(X).reshape(-1, 400, 320, 1, 3)[:1785] # converting list to a numpy array
I get the following error [What happened to 1785?]:
Error when checking input: expected conv_lst_m2d_167_input to have 5 dimensions, but got array with shape (400, 320, 1, 3)
If I add another dimension to the input_shape of the ConvLSTM2D input layer:
model.add(ConvLSTM2D(filters=128, kernel_size=(3, 3), input_shape=(None, 400, 320, 1, 3), padding='same', return_sequences=True))
I get the following error:
ValueError: Input 0 is incompatible with layer conv_lst_m2d_5:expected ndim=5, found ndim=6
At the moment I am just trying to find any situation that actually works so I can go from there. Please help if you can.
Basically I want to know if the issue is in the number of dimensions of my arrays? If so how can I change it?
import numpy as np
import os
import cv2
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers.convolutional import Conv3D
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
DATADIR = "C:/Users/StephanIliffe/Documents/data"
training_data = []
def create_training_data():
path = os.path.join(DATADIR, "Input") # path to jpg precipitation maps
class_num = 1
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path, img))
new_array = cv2.resize(img_array, (400, 320))
training_data.append([new_array, class_num])
create_training_data()
X = []
X_Train = []
X_Test = []
for features, label in training_data:
X.append(features)
X_Train = np.array(X).reshape(-1, 400, 320, 3)[:1785] # converting list to a numpy array
X_Test = np.array(X).reshape(-1, 400, 320, 3)[765:] # converting list to a numpy array
model = Sequential()
model.add(ConvLSTM2D(filters=128, kernel_size=(3, 3),
input_shape=(None, 400, 320, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=128, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=128, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(ConvLSTM2D(filters=128, kernel_size=(3, 3),
padding='same', return_sequences=True))
model.add(BatchNormalization())
model.add(Conv3D(filters=1, kernel_size=(3, 3, 3),
activation='sigmoid',
padding='same', data_format='channels_last'))
model.compile(loss='mean_squared_error', optimizer='adadelta')
model.fit(X_Train, X_Test, batch_size=30, epochs=10, validation_split=0.05)
Well, it's exactly what the error says: expected conv_lst_m2d_167_input to have 5 dimensions, but got array with shape (400, 320, 1, 3). Your input data has four dimensions; it needs to have five: (samples, time, rows, columns, channels).

Error in Convolutional Neural network for input shape

I have 1000, 28*28 resolution images. I converted those 1000 images into numpy array and formed a new array with size of (1000,28,28). So, while
creating convolution layer using keras, input shape(X value) is specified as (1000,28,28) and output shape(Y value) as (1000,10). Because I ha
ve 1000 examples are inputs and 10 categories of output.
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',kernel_initializer='he_normal',input_shape=(1000,28,28)))
.
.
.
model.fit(train_x,train_y,batch_size=32,epochs=10,verbose=1)
So, while using fit function, it shows ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (1000, 28, 28) as error. Pls help me guys to provide proper input and output dimension for CNN.
Code:
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',kernel_initializer='he_normal',input_shape=(4132,28,28)))
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(10, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adam(),metrics=['accuracy'])
model.summary()
train_x = numpy.array([train_x])
model.fit(train_x,train_y,batch_size=32,epochs=10,verbose=1)
You need to change the inputs to 4 dimensions with channel set to 1 : (1000, 28, 28, 1) and you need to change the input_shape of the convolutional layer to (28, 28, 1):
model.add(Conv2D(32, kernel_size=(3, 3),...,input_shape=(28,28,1)))
Your numpy arrays need a fourth dimension, the common standard is to number the samples with the first dimension, so changing (1000, 28, 28) to (1, 1000, 28, 28).
You can read more about this here.
from your input it looks like you are using tensorflow as back end.
In keras the input_shape should always be 3 dimension .
For tensorflow as a backend the input_shape to your model will be
input_shape = [img_height,img_width,channels(depth)]
in your case for tensor flow backend that should be
input_shape = [28,28,1]
and the shape of train_x should be
train_x = [batch_size,img_height,img_width,channels(depth)]
in your case
train_x = [1000,28,28,1]
As you are using a gray scale image,the dimension of the image will be (image_height, image_width) and hence you have to add an extra dimension to the image which will result to (image_height, image_width, 1) the '1' suggests the depth of the image,for gray scale that is '1' and for rgb that is '3'.

Categories

Resources