【问题标题】:Get order of class labels for Keras predict function获取 Keras 预测函数的类标签顺序
【发布时间】:2017-09-15 05:43:17
【问题描述】:

我在 SO 中与this question 有同样的问题。但是,当我尝试使用 probas_to_classes() 实用程序函数时,**当前代码中已经缺少它:

"""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)

为了获得与模型输出相关的类,您还有其他选择吗?

【问题讨论】:

    标签: python classification deep-learning keras


    【解决方案1】:

    正如 matias 正确提出的,你应该使用 np.argmax 函数

    但由于您通常以批次的形式处理输入,因此您的预测输出很可能是一个矩阵。您可以通过分别对每个参数应用 argmax 来处理它,但我认为使用轴参数会更好。

    简而言之:

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

    简而言之,一个可以测试的可运行代码:

    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)
    

    解释:

    首先所有那些 keras 和 numpy 导入和打印功能(因为为什么不)

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

    然后加载mnist数据

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

    之后,使用 to_categorical 将目标类更改为一种热编码

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

    然后回到你需要的课程:

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

    在此示例中,y_test_cat 将是您的 model.predict() 函数的输出,因此您可以将其传递给 argmax 以从最高概率预测中恢复您的类。

    现在,只是为了确保我们的类“预测”完全是原始类(因为它们应该是,因为“预测”已经是正确的类)计算错误。并打印出来

    error = y_test-np.argmax(y_test_cat,axis=1)
    
    all_zero = not np.any(error)
    
    print (all_zero)
    

    【讨论】:

    • 何时使用 argmax 轴作为 1 和 -1 ?有哪些不同的情况?
    【解决方案2】:

    noobalert,要获得前 2 个预测,正如您在 cmets 部分中对 Matias Valdenegro 的问题所要求的那样,您可以执行以下代码:

    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)
    

    【讨论】:

      【解决方案3】:

      更好的选择是使用sklearn 的标签编码器,它正是为此目的而设计的。

      >>> 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]
      

      本质上,这可用于将任何集合(包括包含非数字的集合)映射为整数映射,在训练过程之后可以反转,以便与类标签清晰关联。

      请注意,在 keras 模型中,您可以使用predict_class 函数直接获取转换后的类标签(此时您可以执行inverse_transform),或者如果您想直接从多类输出向量中获取 -这就是当您调用 predict 并对输出层进行 softmax 激活时得到的结果,例如,您可以将其他人提到的 Numpy 的 argmax 与编码器结合使用:

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

      【讨论】:

        【解决方案4】:

        只需在softmax函数的输出上使用numpy的argmax就可以得到概率最大的类。这将返回 [0, N-1] 范围内的类 ID,其中 N 是类数。

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

        【讨论】:

        • 感谢您的回答。但是,我不知道我的类在输出中的顺序。另外,我的计划是通过模型获得前 2 个猜测。你能帮帮我吗?
        猜你喜欢
        • 2020-03-07
        • 1970-01-01
        • 2017-08-23
        • 2020-05-11
        • 2020-03-18
        • 2019-11-06
        • 1970-01-01
        • 2019-09-09
        • 2021-01-02
        相关资源
        最近更新 更多