noobalert
noobalert

Reputation: 865

Get order of class labels for Keras predict function

I have the same question as this question here in SO. However, when I tried using the probas_to_classes() utility function, **it is already missing in the current code:

"""Numpy-related utilities."""
from __future__ import absolute_import

import numpy as np


def to_categorical(y, num_classes=None):
    """Converts a class vector (integers) to binary class matrix.

    E.g. for use with categorical_crossentropy.

    # Arguments
        y: class vector to be converted into a matrix
            (integers from 0 to num_classes).
        num_classes: total number of classes.

    # Returns
        A binary matrix representation of the input.
    """
    y = np.array(y, dtype='int').ravel()
    if not num_classes:
        num_classes = np.max(y) + 1
    n = y.shape[0]
    categorical = np.zeros((n, num_classes))
    categorical[np.arange(n), y] = 1
    return categorical


def normalize(x, axis=-1, order=2):
    """Normalizes a Numpy array.

    # Arguments
        x: Numpy array to normalize.
        axis: axis along which to normalize.
        order: Normalization order (e.g. 2 for L2 norm).

    # Returns
        A normalized copy of the array.
    """
    l2 = np.atleast_1d(np.linalg.norm(x, order, axis))
    l2[l2 == 0] = 1
    return x / np.expand_dims(l2, axis)

Do you have any other alternatives in order to get the classes associated with the output of the model?

Upvotes: 4

Views: 16782

Answers (5)

Davis
Davis

Reputation: 1

To get the top 2 predictions, you slice the list to [:2]

Upvotes: 0

Joel Carneiro
Joel Carneiro

Reputation: 3567

noobalert, to get the top 2 predictions, as you requested to the Matias Valdenegro 's question in the comments section, you can do the following code:

prediction1 = model.predict(your_data)
# sorting the predictions in descending order
sorting = (-prediction1).argsort()

# getting the top 2 predictions
sorted_ = sorting[0][:2]

for value in sorted_:
    # you can get your classes from the encoder(your_classes = encoder.classes_) 
    # or from a dictionary that you created before.
    # And then we access them with the predicted index.
    predicted_label = your_classes[value]

    # just some rounding steps
    prob = (prediction1[0][value]) * 100
    prob = "%.2f" % round(prob,2)
    print("I have %s%% sure that it belongs to %s." % (prob, predicted_label)

Upvotes: 2

rvd
rvd

Reputation: 568

A better option is to use sklearn's label encoder, which is designed for exactly this purpose.

>>> from sklearn.preprocessing import LabelEncoder()
>>> le = LabelEncoder()
>>> le.fit_tranform([1, 2, 2, 6])
array([0, 0, 1, 2])
>>> le.inverse_transform([0, 0, 1, 2])
[1, 2, 2, 6]

Essentially, this can be used to map any collection (including those containing non-numerics) into an integer mapping in a way that can be reversed after the training process in order to cleanly associate with class labels.

Note that in a keras model, you can use the predict_class function to get the transformed class labels directly (at which point you can perform the inverse_transform) or if you want to go from the multiclass output vector directly - which is what you get when you call predict and have a softmax activation for the output layer, for instance, you can use Numpy's argmax as has been mentioned by others in conjunction with the encoder:

true_labels = le.inverse_transform(list(map(lambda x: np.argmax(x))))

Upvotes: 2

maz
maz

Reputation: 1980

As correctly presented by matias, you should use np.argmax function

But since you usually deal with inputs in batches your prediction output will most likely be a matrix. You can deal with it by applying argmax to each one individually, but I think it's better to use the axis argument.

In short:

predictions = model.predict(Input)
classes = np.argmax(predictions, axis=1)

In not so short, a runnable code you can test:

from __future__ import print_function
import keras
import numpy as np
from keras.datasets import mnist



(x_train, y_train), (x_test, y_test) = mnist.load_data()
num_classes = 10
y_test_cat = keras.utils.to_categorical(y_test, num_classes)
print(y_test)
print(np.argmax(y_test_cat,axis=1))

error = y_test-np.argmax(y_test_cat,axis=1)

all_zero = not np.any(error)

print (all_zero)

Explanation:

First all those keras and numpy imports and print function (because why not)

from __future__ import print_function
import keras
import numpy as np
from keras.datasets import mnist

Then load mnist data

(x_train, y_train), (x_test, y_test) = mnist.load_data()

After that, change your target classes to one hot encoding with to_categorical

y_test_cat = keras.utils.to_categorical(y_test, num_classes)

Then go back to the classes you need:

print(np.argmax(y_test_cat,axis=1))

In this example, y_test_cat would be the output of your model.predict() function, so that's how you'd pass it to argmax to recover your class from highest probability prediction.

Now, just to make sure our classes "predictions" are exactly the original classes (as they should be since the "predictions" were already the right classes) the error is computed. and printed

error = y_test-np.argmax(y_test_cat,axis=1)

all_zero = not np.any(error)

print (all_zero)

Upvotes: 7

Dr. Snoopy
Dr. Snoopy

Reputation: 56357

Just use numpy's argmax on the output of the softmax function to get the class with maximum probability. This will return the class ID in the range [0, N-1], where N is the number of classes.

pred = model.predict(data here)[0]
classes = np.argmax(pred)

Upvotes: 0

Related Questions