model.predict throws ValueError: expected shape=(None, 64, 64, 3), found shape=(None, 64, 3)

Question:

I modeled the following convolutional neural network (CNN) using tensorflow within a google colab notebook:

import tensorflow as tf

PATCHSIZE = 64

# CNN model
model = tf.keras.models.Sequential([
    # Convolutional layer. Learn 32 filters using a 3x3 kernel
    tf.keras.layers.Conv2D(32, (3, 3), activation="relu", input_shape=(PATCHSIZE, PATCHSIZE, 3)),

    #Max-pooling layer, using 2x2 pool size
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),

    # Flatten units
    tf.keras.layers.Flatten(),
    # Add a hidden layer with dropout
    tf.keras.layers.Dense(128, activation="relu"),
    tf.keras.layers.Dropout(0.5),

    # Add an output layer with one output unit for a probability
    tf.keras.layers.Dense(1, activation="sigmoid")
])

model.compile(
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=["accuracy"]
)

training_patches = []
training_labels = []

training_patches = np.array(training_patches)
training_labels = np.array(training_labels)

model.fit(training_patches, training_labels, epochs=20)

validation_patches = np.array(validation_patches)
validation_labels = np.array(validation_labels)

model.evaluate(validation_patches, validation_labels, verbose=2)

The input data (patches) are color images of the size 64×64 pixels. So the input shape is (64, 64, 3). The training and evaulation process worked fine, but when I try to predict the probability of an input patch (a numpy array with the shape (64, 64, 3) I got the following error:

throws  ValueError: Input 0 of layer "sequential_6" is incompatible with the layer: expected shape=(None, 64, 64, 3), found shape=(None, 64, 3)
 # throws  ValueError: Input 0 of layer "sequential_6" is incompatible with the layer: expected shape=(None, 64, 64, 3), found shape=(None, 64, 3)
model.predict(patch)

What am I doing wrong?

Asked By: Dawid

||

Answers:

The problem is that you are not specifying the batch dimension. Try this code:

import tensorflow as tf
import numpy as np

PATCHSIZE = 64

# CNN model
model = tf.keras.models.Sequential([
    # Convolutional layer. Learn 32 filters using a 3x3 kernel
    tf.keras.layers.Conv2D(32, (3, 3), activation="relu", input_shape=(PATCHSIZE, PATCHSIZE, 3)),

    #Max-pooling layer, using 2x2 pool size
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),

    # Flatten units
    tf.keras.layers.Flatten(),
    # Add a hidden layer with dropout
    tf.keras.layers.Dense(128, activation="relu"),
    tf.keras.layers.Dropout(0.5),

    # Add an output layer with one output unit for a probability
    tf.keras.layers.Dense(1, activation="sigmoid")
])

model.compile(
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=["accuracy"]
)

training_patches = np.ones((1, PATCHSIZE, PATCHSIZE, 3))
training_labels = np.ones((1, 1))

model.fit(training_patches, training_labels, epochs=20)

validation_patches = np.ones((1, PATCHSIZE, PATCHSIZE, 3))
validation_labels = np.ones((1, 1))

model.evaluate(validation_patches, validation_labels, verbose=2)

If you have a single validation_patch, an easy way to add a dimension to an already existing numpy array is like this:

my_array = np.ones((64, 64, 3))
print(my_array.shape)  # output: (64, 64, 3)
my_array = np.expand_dims(my_array, axis=0)
print(my_array.shape)  # output: (1, 64, 64, 3)
Answered By: ClaudiaR