Hey
So I am doing the machine learning with python course with free code camp and I’m stuck with this problem for days. I finished the pretrained model section and I wanted to try and use predict on the model after I saved it and loaded it on another file. I take a path from the user and it is supposed to give some output but instead an error pops:
ValueError: Input 0 is incompatible with layer sequential: expected shape=(None, 160, 160, 3), found shape=(32, 160, 3)
I know it has to do with the shape of the input image, but even after i resize it i get the same:
import tensorflow as tf
import cv2
input_path = input('enter dog or cat pic path: ')
image = cv2.imread(f'{input_path}', cv2.IMREAD_UNCHANGED)
print(image.shape)
image = tf.image.resize(image, (160, 160))
print(image.shape)
model = tf.keras.models.load_model('dogs_vs_cats.h5')
model.predict(image)
the output of the print statements gives this:
(183, 275, 3)
(160, 160, 3)
Here you can see how the image is reshaped but the error still pops up and even says that the found shape is (32, 160, 3) for some reason.
Here is the code of the model that I copied from tech with tim’s lesson on Free Code Camp about using pretrained models:
import tensorflow as tf
import tensorflow_datasets as tfds
keras = tf.keras
# split the data manually into 80% training, 10% testing, 10% validation
(raw_train, raw_validation, raw_test), metadata = tfds.load(
'cats_vs_dogs',
split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
with_info=True,
as_supervised=True,
)
get_label_name = metadata.features['label'].int2str # creates a function object that we can use to get labels
"""""
Since the sizes of our images are all different, we need to convert them all to the same size.
We can create a function that will do that for us below.
"""""
IMG_SIZE = 160 # All images will be resized to 160x160
def format_example(image, label):
"""
returns an image that is reshaped to IMG_SIZE
"""
image = tf.cast(image, tf.float32)
image = (image / 127.5) - 1
image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))
print(image.shape)
return image, label
# Now we can apply this function to all our images using .map().
# .map() takes every single example in raw_train, raw_validation, etc and applies the function to it
train = raw_train.map(format_example)
validation = raw_validation.map(format_example)
test = raw_test.map(format_example)
BATCH_SIZE = 32
SHUFFLE_BUFFER_SIZE = 1000
# Finally we will shuffle and batch the images
train_batches = train.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
validation_batches = validation.batch(BATCH_SIZE)
test_batches = test.batch(BATCH_SIZE)
"""""
Picking a Pretrained Model
The model we are going to use as the convolutional base for our model is the MobileNet V2 developed at Google.
This model is trained on 1.4 million images and has 1000 different classes.
We want to use this model but only its convolutional base. So, when we load in the model,
we'll specify that we don't want to load the top (classification) layer. We'll tell the model what input
shape to expect and to use the predetermined weights from imagenet (Googles dataset).
"""""
IMG_SHAPE = (IMG_SIZE, IMG_SIZE, 3)
# Create the base model from the pre-trained model MobileNet V2
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
include_top=False, # we don't want to load the top layer
weights='imagenet')
"""""
Freezing the Base
The term freezing refers to disabling the training property of a layer. It simply means we won’t make any
changes to the weights of any layers that are frozen during training.
This is important as we don't want to change the convolutional base that already has learned weights.
"""""
base_model.trainable = False
"""""
Adding OUR Classifier
Now that we have our base layer setup, we can add the classifier. Instead of flattening the feature map
of the base layer we will use a global average pooling layer that will average the entire 5x5 area of each
2D feature map and return to us a single 1280 element vector per filter.
"""""
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
# Finally, we will add the prediction layer that will be a single dense neuron. We can do this because we
# only have two classes to predict for.
prediction_layer = keras.layers.Dense(1)
# Now we will combine these layers together in a model.
model = tf.keras.Sequential([
base_model,
global_average_layer,
prediction_layer
])
# TRAINING THE MODEL
"""""
Now we will train and compile the model. We will use a very small learning rate to ensure that the model
does not have any major changes made to it.
"""""
base_learning_rate = 0.0001
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
# Now we can train it on our images
initial_epochs = 3
history = model.fit(train_batches,
epochs=initial_epochs,
validation_data=validation_batches)
acc = history.history['accuracy']
print(acc)
# you can save a model and load a model with this syntax so you don't have to train it again every time
model.save("dogs_vs_cats.h5") # we can save the model and reload it at anytime in the future
Notice that the predict method is used in a different file after the model is saved and loaded again to avoid trainig the model everytime.
Thank you in advance!