【问题标题】:How Tensorflow & Keras go from one-hot encoded outputs to class predictions for calculating the accuracy?Tensorflow 和 Keras 如何从 one-hot 编码输出到类别预测以计算准确度?
【发布时间】:2020-08-16 19:57:21
【问题描述】:

我想知道 TensorFlow/Keras 中的准确度指标如何计算给定输入是否与预期预测匹配,或者换句话说,它如何确定网络的预测数量。


示例 1:

输出:[0, 0, 0.6],预期输出:[0, 0, 1]

我假设 0.6 只是四舍五入到 1,对吗?或者它被视为唯一大于 0.5 的数字,因此它是预测数字。

但是,如果是这样,那么请考虑 示例 2:

输出:[0.6, 2, 0.1],预期输出:[1, 0, 0]

我知道,softmax 无法实现这样的输出,这将是这里的默认选择。但它可能与其他激活函数一起使用。

现在这里只是“提取”并作为预测的最大数字吗?所以2,什么是错误的预测。

示例 3:

输出:[0.1, 0, 0.2],预期输出:[0, 0, 1]

由于输出中的每个数字都小于 0.5,我猜精度计算器会将此输出视为 [0, 0, 0],因此也不是正确的预测。对吗?


如果我之前的假设是正确的,那么规则如下?

每个小于0.5的数字在预测方面都是0,从大于0.5或等于0.5的数字中我选择最大的一个。然后最大的代表预测的类别。


如果是这样,那么准确率只能用于只有一个对应正确类别的分类(例如,不能有像 [1, 0, 1] 这样的预期输出)?

【问题讨论】:

    标签: python tensorflow machine-learning keras


    【解决方案1】:

    默认情况下,Keras 使用的准确度是分类准确度,这似乎是适合您的情况。它计算多类分类问题的所有预测的平均准确率。

    它的代码如下:

    def categorical_accuracy(y_true, y_pred):
        return K.mean(K.equal(K.argmax(y_true, axis=-1), K.argmax(y_pred, axis=-1)))
    

    意思是例子1

    [0, 0, 0.6]
    

    将是

    [0, 0, 1]
    

    示例 2

    [0.6, 2, 0.1]
    

    将是

    [0, 1, 0]
    

    示例 3

    [0.1, 0, 0.2]
    

    将会

    [0, 0, 1]
    

    然后将这些与目标进行比较

    [0, 0, 1], [1, 0, 0], [0, 0, 1] 
    

    如果您预测这三个示例会给出这些示例的平均值,那么您的准确度将是

    0.66
    

    【讨论】:

    • 非常感谢这个出色的答案!我还有一个问题:因此,如果您还有像 [0, 0 ,0] 这样的输出但没有正确分类,您就不能使用 Accuracy?
    • Argmax 将始终为您提供最高值的索引,所以不会。
    • @LukasNießen 这个问题纯粹是学术性的;只要您正确设置了多类问题,就永远不会有这样的输出。
    【解决方案2】:

    您的问题有几个问题。

    首先,我们必须澄清确切的设置;所以,在 single-label multi-class 分类中(即一个样本可以属于一个且只属于一个类)与 one-hot 编码样本(和预测),你在这里展示的所有例子都是 无效:输出数组的元素不仅小于 1,而且必须相加为 1(因为它们被视为概率)。

    澄清这一点后,很容易看出没有必要对任何值设置阈值(例如,按照您在此处的建议,设置为 0.5);您只需拨打argmax。所以,[0.25. 0.35. 0.4] 变成了[0, 0, 1]

    从这个例子中,也应该很明显,在这样的设置中,可能存在没有单个元素大于 0.5 的情况,这是很自然的。似乎新从业者容易混淆 0.5 在这里扮演了一些特殊的角色,就像它仅在 binary 分类中一样;但在多类分类中,0.5不再起任何特殊作用; (单标签)多类设置中的等效“阈值”是1/n,其中n 是类数(在此示例中为 0.33,因为我们有 3 个类)。很容易看出,考虑到数组元素应该小于 1 并且加起来为 1 的约束,总会有一个大于 0.33 的条目。但只需使用argmax 即可完成工作,无需任何中间阈值。

    我知道,softmax 不可能有这样的输出,这将是这里的默认选择。但它可能与其他激活函数一起使用。

    只要我们继续讨论有意义的分类设置(而不仅仅是做一些疯狂的计算实验),这是正确的;唯一其他可能的分类激活函数是sigmoid,它再次给出小于1的结果(尽管不再等于1)。你当然可以在最后一层请求linear(甚至relu)激活;您的程序不会崩溃,但这并不意味着从建模的角度来看您正在做任何有意义的,我相信这是您真正感兴趣的。

    那么准确率只能用于只有一个对应正确类别的分类(例如,不能有像[1, 0, 1] 这样的预期输出)?

    这是一个完全不同的上下文,称为多标签多类分类(即一个样本可以属于多个类)。现在应该很清楚,像[1, 0, 1] 这样的结果永远不会出现在单标签多类案例的情况下(即,如果您的真实标签中已经没有这样的案例)。一般情况见What are the measure for accuracy of multilabel data?How does Keras handle multilabel classification?(提示:sigmoid)。

    【讨论】:

    • 非常感谢,这对我帮助很大!实际上,我正在考虑像linear 这样的最后一层激活函数,只是为了了解准确性的工作方式(尽管这没有意义)。但是,所以我现在假设,在二进制分类中,0.5 很重要,因为如果输出较小,那么在分类术语中它是 0,否则是 1。很高兴知道,0.5 的这种处理仅在二进制分类中进行,我不知道单标签、多标签、二进制等之间的区别。无论如何,我现在知道了,非常感谢。
    • @LukasNießen 不客气;如您所见,在 multi-label 的情况下,0.5 可能会再次发现一些特殊的重要性(但我不得不在某个时候结束答案)。
    猜你喜欢
    • 1970-01-01
    • 2019-07-14
    • 2017-06-21
    • 2018-05-09
    • 1970-01-01
    • 2019-05-06
    • 2021-08-05
    • 2017-02-28
    • 1970-01-01
    相关资源
    最近更新 更多