使用 round 或 argmax 评估 Tensorflow 中的 softmax(分类)准确性



>问题

我尝试用 Tensorflow 制作一个 softmax 分类器,并用 tf.argmax() 进行预测。我发现y_中的一个总是高于 0.5,我用tf.round()而不是tf.argmax()

但是,这两种方法之间的精度差距约为20% - tf.round()的精度高于tf.argmax()

我预计这两种方法的准确性应该完全相同,或者tf.round()应该低于tf.argmax(),但事实并非如此。有谁知道为什么会这样?

Y 和 y_

Y=[[1,0,0],
[0,1,0],
[0,0,1], ......]  : One-hot (target)
y_=[[0.92, 0.4, 0.4],
[0.2,0.6,0.2],
[0.2,0.4,0.2], ......] : output of softmax

正确的预测

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
correct_prediction = tf.equal(tf.round(y), tf.round(y_))

准确性

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

这个问题有点老了,但有人可能会像我一样偶然发现它......

总之:

  • tf.argmax减少 axis 参数指定的一个维度,它将索引返回到沿该的最大值
  • tf.round对每个值进行舍入,返回与输入相同的形状
  • 使用tf.round的"精度"将随着指定的尺寸长度而增加

例如

y = [
    [1.0, 0.0, 0.0],
    [0.0, 1.0, 0.0],
    [0.0, 0.0, 1.0]
]
y_ = [
    [0.92, 0.4, 0.4],
    [0.2,0.6,0.2],
    [0.2,0.4,0.2]
]
print('argmax shape:', tf.argmax(y_, 1).shape)
print('round shape:', tf.round(y_).shape)
with tf.Session():
    print('argmax value', tf.argmax(y_, 1).eval())
    print('round value', tf.round(y_).eval())
    correct_prediction_argmax = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    correct_prediction_round = tf.equal(tf.round(tf.cast(y, tf.float32)), tf.round(y_))
    print('argmax accuracy:', tf.reduce_mean(tf.cast(correct_prediction_argmax, tf.float32)).eval())
    print('round accuracy:', tf.reduce_mean(tf.cast(correct_prediction_round, tf.float32)).eval())

输出:

argmax shape: (3,)
round shape: (3, 3)
argmax value [0 1 1]
round value [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 0.]]
argmax accuracy: 0.6666667
round accuracy: 0.8888889

您可以看到,使用 tf.round 通常会为每行上的两个额外零获得分数

最新更新