Keras - categorical_accuracy 和 sparse_categorical_accuracy 之间的区别

Posted

技术标签:

【中文标题】Keras - categorical_accuracy 和 sparse_categorical_accuracy 之间的区别【英文标题】:Keras - Difference between categorical_accuracy and sparse_categorical_accuracy 【发布时间】:2017-11-12 15:13:22 【问题描述】:

Keras 中的categorical_accuracysparse_categorical_accuracy 有什么区别? documentation for these metrics 中没有任何提示,通过询问 Google 博士,我也没有找到答案。

源码可以找到here:

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


def sparse_categorical_accuracy(y_true, y_pred):
    return K.cast(K.equal(K.max(y_true, axis=-1),
                          K.cast(K.argmax(y_pred, axis=-1), K.floatx())),
                  K.floatx())

【问题讨论】:

也许这会有所帮助:***.com/a/43546939/3374996。与目标有关。我不确定目标是否意味着 y_true、y_pred 是稀疏的,或者分类精度的输出是稀疏的。 很糟糕,这既不在文档中,也不在文档字符串中。 【参考方案1】:

sparse_categorical_accuracy 需要稀疏目标

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

例如:

import tensorflow as tf

sparse = [[0], [1], [2]]
logits = [[.8, .1, .1], [.5, .3, .2], [.2, .2, .6]]

sparse_cat_acc = tf.metrics.SparseCategoricalAccuracy()
sparse_cat_acc(sparse, logits)
<tf.Tensor: shape=(), dtype=float64, numpy=0.6666666666666666>

categorical_accuracy 期望一个热编码目标

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

例如:

onehot = [[1., 0., 0.],  [0., 1., 0.], [0., 0., 1.]]
logits = [[.8, .1, .1], [.5, .3, .2], [.2, .2, .6]]

cat_acc = tf.metrics.CategoricalAccuracy()
cat_acc(sparse, logits)
<tf.Tensor: shape=(), dtype=float64, numpy=0.6666666666666666>

【讨论】:

【参考方案2】:

我刚刚提到的一个区别是指标名称的不同。

使用categorical_accuracy,这行得通:

mcp_save_acc = ModelCheckpoint('model_' + 'val_accval_accuracy:.3f.hdf5', save_best_only=True, monitor='val_accuracy', mode='max')

但是在切换到sparse_categorical accuracy 之后,我现在需要这个:

mcp_save_acc = ModelCheckpoint('model_' + 'val_accval_sparse_categorical_accuracy:.3f.hdf5', save_best_only=True, monitor='val_sparse_categorical_accuracy', mode='max')

即使我仍然有 metrics=['accuracy'] 作为我的 compile() 函数的参数。

我有点希望 val_acc 和/或 val_accuracy 只是为所有 keras 的内置 *_crossentropy 损失工作。

【讨论】:

这很有趣,有用且具有实用价值,但与问题无关。充其量应该是一条评论。【参考方案3】:

看着source

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


def sparse_categorical_accuracy(y_true, y_pred):
    return K.cast(K.equal(K.max(y_true, axis=-1),
                          K.cast(K.argmax(y_pred, axis=-1), K.floatx())),
K.floatx())

categorical_accuracy 检查最大真值的 index 是否等于最大预测值的 index

sparse_categorical_accuracy 检查最大真值是否等于最大预测值的索引

从上面 Marcin 的回答中,categorical_accuracy 对应于 y_trueone-hot 编码向量。

【讨论】:

我们不是在稀疏模式下传递整数而不是单热向量吗?为什么它在 K.max(y_true, axis=-1) 行中取最大值? :/ 我的意思是 y_true 中不应该只有一个值吗?【参考方案4】:

因此,在categorical_accuracy 中,您需要将目标 (y) 指定为 one-hot 编码向量(例如,在 3 个类的情况下,当真正的类是第二类时,y 应该是 (0, 1, 0)。在sparse_categorical_accuracy 中,您只需要提供一个真实类的整数(在前面示例中的情况下,它将是1,因为类索引是基于0)。

【讨论】:

@MarcinMożejko 我认为您的术语是错误的-在稀疏分类准确性方面,您不需要提供整数-而是可以提供长度为 1 且仅包含索引的数组 - 因为 keras 从数组中选择最大值 - 但您也可以提供任意长度的数组 - 例如三个结果 - 并且 keras 将从该数组中选择最大值并检查是否对应y_pred中最大值的索引 @aviv 后续问题 - 这与“准确性”有何不同?谢谢。 @user3303020 当您告诉 keras 使用 "accuracy" 时,keras 使用的是默认精度 categorical_accuracy 如果您查看keras.io/api/metrics/accuracy_metrics/#accuracy-class,我认为 categorical_accuracy 要求标签是一种热编码,而为了准确性,标签不能是一种热编码。我自己的测试证实了这一点。

以上是关于Keras - categorical_accuracy 和 sparse_categorical_accuracy 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

keras如何快速入门

keras与tensorflow.python.keras - 使用哪一个?

keras 与 tensorflow.python.keras - 使用哪一个?

keras是啥

Tensorflow+Keras用Tensorflow.keras的方法替代keras.layers.merge

Tensorflow+Keras用Tensorflow.keras的方法替代keras.layers.merge