ValueError: `decode_predictions` expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 7)
Asked Answered
S

2

5

I am using VGG16 with keras for transfer learning (I have 7 classes in my new model) and as such I want to use the build-in decode_predictions method to output the predictions of my model. However, using the following code:

preds = model.predict(img)

decode_predictions(preds, top=3)[0]

I receive the following error message:

ValueError: decode_predictions expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 7)

Now I wonder why it expects 1000 when I only have 7 classes in my retrained model.

A similar question I found here on stackoverflow (Keras: ValueError: decode_predictions expects a batch of predictions ) suggests to include 'inlcude_top=True' upon model definition to solve this problem:

model = VGG16(weights='imagenet', include_top=True)

I have tried this, however it is still not working - giving me the same error as before. Any hint or suggestion on how to solve this issue is highly appreciated.

Solorio answered 13/3, 2018 at 14:57 Comment(0)
L
11

i suspect you are using some pre-trained model, let's say for instance resnet50 and you are importing decode_predictions like this:

from keras.applications.resnet50 import decode_predictions

decode_predictions transform an array of (num_samples, 1000) probabilities to class name of original imagenet classes.

if you want to transer learning and classify between 7 different classes you need to do it like this:

base_model = resnet50 (weights='imagenet', include_top=False)

# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a logistic layer -- let's say we have 7 classes
predictions = Dense(7, activation='softmax')(x) 
model = Model(inputs=base_model.input, outputs=predictions)
...

after fitting the model and calculate predictions you have to manually assign the class name to output number without using imported decode_predictions

Lum answered 13/3, 2018 at 15:9 Comment(2)
Thank you very much for your answer. So do I understand you correclty that it is not possible to use decode_predictions when retraining a model with a class-size that is not equal to the original model? If so, is there no way to tell the decode_predictions that the number of classes has changed?Solorio
yes. In order to be able to use decode_predictions you have to have a vector of 1000 probabilitiesLum
N
0

Overloading of 'decode_predictions' function.Comment out the 1000 classes constraints of original function:

CLASS_INDEX = None
@keras_modules_injection
def test_my_decode_predictions(*args, **kwargs):
    return my_decode_predictions(*args, **kwargs)


def my_decode_predictions(preds, top=5, **kwargs):
    global CLASS_INDEX

    backend, _, _, keras_utils = get_submodules_from_kwargs(kwargs)

    # if len(preds.shape) != 2 or preds.shape[1] != 1000:
    #     raise ValueError('`decode_predictions` expects '
    #                      'a batch of predictions '
    #                      '(i.e. a 2D array of shape (samples, 1000)). '
    #                      'Found array with shape: ' + str(preds.shape))
    if CLASS_INDEX is None:
        fpath = keras_utils.get_file(
            'imagenet_class_index.json',
            CLASS_INDEX_PATH,
            cache_subdir='models',
            file_hash='c2c37ea517e94d9795004a39431a14cb')
        with open(fpath) as f:
            CLASS_INDEX = json.load(f)
    results = []
    for pred in preds:
        top_indices = pred.argsort()[-top:][::-1]
        result = [tuple(CLASS_INDEX[str(i)]) + (pred[i],) for i in top_indices]
        result.sort(key=lambda x: x[2], reverse=True)
        results.append(result)
    return results


print('Predicted: ', test_my_decode_predictions(pred, top=10))
Nutlet answered 26/3, 2020 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.