Keras pre-built VGG16 - do you switch data to BGR? Subtract the mean?

In the lesson 1 notebook, Jeremy does not convert the incoming images to BGR, nor does he subtract the mean from the images when he uses Keras’ pre-built VGG. Later, however, when we reconstruct it, we include the lambda layer to convert the images and subtract the mean from the image data.

The Keras code for VGG, does neither of these steps. Yet the VGG example in lesson 1 works swimmingly. Does anyone have any idea why? Am I missing something here?

OK, so the Vgg16 function we’re using in the notebooks isn’t the Keras one - it’s one Jeremy made adding back in Dropout to VGG and taking care of the preprocessing.

So on the built in Keras, we’d have to pre-process the images prior to passing into the net?

I was just going to ask this exact same question. I am working on using vgg for this challenge: https://www.hackerearth.com/challenge/competitive/deep-learning-challenge-1.

My code looks like this:

vgg16 = VGG16()
vgg16.layers.pop()
vgg16.layers.pop()
for layer in vgg16.layers: layer.trainable=False
m = Dense(4096)(vgg16.layers[-1].output)
m = Dense(25,activation='softmax')(m)
vgg16 = Model(vgg16.input, m)
vgg16.compile(optimizer="adam",loss="categorical_crossentropy")

Then when I try to fit it, I get this output:

fit:

vgg16.fit(train_data, train_label, epochs=50, batch_size=64)
Epoch 1/50
3215/3215 [==============================] - 11s - loss: 15.0619    
Epoch 2/50
3215/3215 [==============================] - 11s - loss: 15.5215    
Epoch 3/50
3215/3215 [==============================] - 11s - loss: 15.5215    
Epoch 4/50
3215/3215 [==============================] - 11s - loss: 15.5215    

Have you ran into this at all? I’m wondering if maybe this is because I didn’t do the BGR conversion or mean subtraction?

It’s unclear in your example - is that the Keras vgg or Jeremy’s VGG? It seems to me for the Keras pre-built vgg the answer is you MUST pre-process your images (RGB->BGR + mean subtraction) prior to using - I just can’t find anything about it but there’s nothing in the codebase for that model to suggest its done for you.

First do:

from keras.applications.vgg16 import preprocess_input
from keras.preprocessing import image

then to load and process your images:

img = image.load_img(img_path, target_size=(img_height, img_width))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

Now x contains an image that has the VGG16 preprocessing applied to it.

3 Likes

IIRC this switches channels by default. BTW do you know if this can be used with a generator? I’m thinking we should still be good to use it with the Lambda layer

You can write:

dategen = keras.preprocessing.image.ImageDataGenerator(preprocessing_function=preprocess_input)

(and whatever other parameters you want to pass in for data augmentation etc).

2 Likes

Great tip, thanks for the information. One cool think I just realized I could do is use the ?? on my variables which helped me see the different commands I have available. Thanks again for your help on this.

Does this still work with the new Keras API?

Not sure what new Keras API you’re referring to, but yes it still works. :slight_smile: