keras-team / keras-applications

Reference implementations of popular deep learning models.
Other
2k stars 910 forks source link

Pre-trained Resnet50 predicts the same class for different images. #64

Closed rbahumi closed 5 years ago

rbahumi commented 5 years ago

Keras version: 2.2.4 Backend: Tensorflow

I am loading Resnet50 model pre-trained on imagenet and getting a prediction for the 'nematode' class for different images. Using the same methods with InceptionV3 return different (correct) results for different images.

Resnet50 weights are loaded from resnet50_weights_tf_dim_ordering_tf_kernels.h5

How to recreate:

Helper functions I defined and used:

import os
import requests
import random
import string
from IPython.display import Image, display
from IPython.core.display import HTML
import keras
from keras.preprocessing import image
from keras.applications.imagenet_utils import decode_predictions

## Helper methods for downloading an image from a url
def download_file(url, filename):
    response = requests.get(url)
    response.raise_for_status()

    with open(filename, 'wb') as f:
        f.write(response.content)

def gen_random_str(k=16):
    rand_array = [random.choice(string.ascii_letters + string.digits) for i in range(k)]
    return ''.join(rand_array)

def download_url_to_random_filename(url):
    tmp_filename = os.path.join("/tmp", "%s.jpg" % gen_random_str(k=16))
    download_file(url, tmp_filename)
    return tmp_filename

# Prediction methods for local/remote files
def pred_image(model, image_path):
    img = image.img_to_array(image.load_img(image_path, target_size=(224, 224))) / 255.
    res = model.predict(img.reshape((1,) + img.shape))
    return decode_predictions(res)

def pred_image_from_url(model, url):
    tmp_filename = download_url_to_random_filename(url)
    res = pred_image(model, tmp_filename)
    os.remove(tmp_filename)
    return res
# Load resnet50 and InceptionV3 models
resnet_model = keras.applications.resnet50.ResNet50(include_top=True, weights='imagenet')
inception_model = keras.applications.inception_v3.InceptionV3(weights='imagenet')

Chose two random images of a cat and a dog:

from IPython.display import Image, display
from IPython.core.display import HTML

cat_url = "https://upload.wikimedia.org/wikipedia/commons/c/c0/Ragdoll_Blue_Colourpoint.jpg"
dog_url = "https://www.purina.co.nz/wp-content/uploads/2013/10/ChineseSharPei_body.jpeg"

display(Image(url=cat_url, width=200, height=200))
display(Image(url=dog_url, width=200, height=200))
cat_and_dog

And queried them against the model:

pred_image_from_url(resnet_model, cat_url)
pred_image_from_url(resnet_model, dog_url)
pred_image_from_url(inception_model, cat_url)
pred_image_from_url(inception_model, dog_url)
screen shot 2019-01-25 at 23 44 08

I tried with other images, the Resnet50 model predicts the 'nematode' class for them as well...

rbahumi commented 5 years ago

I am closing this issue, the resnet50 model requires a preprocessing step (the function keras.applications.resnet50.preprocess_input()).