Search code examples
pythonkerasdeep-learningconv-neural-networktransfer-learning

how to change the input shape of bottleneck features after importing from Vgg16 net


I am trying to use VGG16 Net for training a model to do image classification and want to transfer the weights without Dense layer to my set of images with this code.

model1 = applications.VGG16(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))

After learning the bottleneck features the last few layers of the model are:

block5_conv2 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 3, 3, 512)         0         
=================================================================

Last layer dimension is (None,3,3,512). This will be the input to my Dense layer.

model1 = Sequential()
model1.add(Flatten(input_shape=train_data.shape[1:]))

So the input shape to the model is (3,3,512). My Problem is that when I am trying to predict the image, the size of the input image is (224,224,3). So how can I convert the shape of my input image to the input shape of my model?

When I try to predict it, this is the error I received:

ValueError: Error when checking input: expected flatten_1_input to have a shape (3, 3, 512) but got array with shape (224, 224, 3)

How can I change the input shape of the model or input shape of the input image which I have to predict?


Solution

  • The input of Flatten layer is the output of VGG16 model (actually its convolutional base since you are removing the dense classifier at the top) and not your image. And the VGG16 model already has an input layer so there is no need to create another one. Therefore you can do it like this:

    vgg_base = applications.VGG16(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))
    
    model = Sequentail(vgg_base)
    model.add(Flatten())
    # the rest of the layers you want to add
    

    VGG16 is a sequential model so the above approach works. However, for other models which don't have a sequential architecture you need use the Keras Functional API.


    I could not understand from your post that you are performing feature extraction + classification at the same time or you have already extracted the features and now you want to use them to classify your images. The above method is for the former case. But for the latter case, as I mentioned before, the input of Flatten layer is the extracted features (i.e. output of VGG16 base) and not the images. Therefore you must set the input_shape argument correctly:

    model = Sequentail()
    model.add(Flatten(input_shape=(3,3,512))
    # the rest of the layers