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 64x64 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?
CodePudding user response:
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)