Keras - categorical_accuracy和sparse_categorical_accuracy之间的区别

72
在 Keras 中,categorical_accuracysparse_categorical_accuracy 有什么区别?在度量指标的文档中没有任何提示,通过在 Google 上搜索也没有找到答案。

源代码可以在这里找到:

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

1
也许这可以帮助:https://dev59.com/LlcP5IYBdhLWcg3w-Otz#43546939。与目标有关的一些内容。我不确定他们所说的目标是指y_true,y_pred是否稀疏或分类准确性的输出是否稀疏。 - Vivek Kumar
2
很遗憾,这个内容既不在文档中,也不在文档字符串中。 - Denziloe
4个回答

90

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


1
@MarcinMożejko 我认为你在术语上是错误的 - 在稀疏分类准确性中,您不需要提供整数 - 相反,您可以提供一个仅包含索引的长度为一的数组 - 因为keras从数组中选择最大值 - 但您也可以提供任意长度的数组 - 例如三个结果的数组 - keras将从该数组中选择最大值,并检查它是否对应于y_pred中最大值的索引。 - aviv
2
@aviv 跟进问题 - 这与“准确性”有何不同?谢谢。 - user3303020
6
当你告诉 Keras 使用 "accuracy" 时,Keras 正在使用默认的准确率,即 "categorical_accuracy"。 - aviv
1
如果您查看https://keras.io/api/metrics/accuracy_metrics/#accuracy-class,我认为categorical_accuracy需要标签进行one-hot编码,而对于accuracy指标,标签不能进行one-hot编码。我的测试证实了这一点。 - user4918159

53

查看源代码

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 检查最大真实值的索引是否等于最大预测值的索引。

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

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


1
我们在稀疏模式下传递的不是one-hot向量而是整数,那么为什么在K.max(y_true, axis=-1)中要取最大值呢? :/ y_true中不应该只有一个值吗? - leo

17

sparse_categorical_accuracy 期望使用 稀疏目标值(sparse targets)

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

0

我最近遇到的一个不同之处是指标名称的差异。

使用categorical_accuracy,这个运行正常:

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

但是在切换到"sparse_categorical_accuracy"之后,我现在需要这个:
mcp_save_acc = ModelCheckpoint('model_' + 'val_acc{val_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损失。


1
这很有趣,有用且实用,但与问题无关。最好只是一条评论。 - Volker Siegel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接