Top-k准确率

1
2
3
4
5
import  tensorflow as tf
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #限制控制台打印日志级别
tf.random.set_seed(2467)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def accuracy(output, target, topk=(1,)):
# output [10,6]
maxk = max(topk)
batch_size = target.shape[0]

pred = tf.math.top_k(output, maxk).indices # 前K个最大值的索引 [10,maxk]
# print('每行top-6 最大值',tf.math.top_k(output, maxk).values)
print('每行top-6 最大值下标',tf.math.top_k(output, maxk).indices)
pred = tf.transpose(pred, perm=[1, 0]) # 转置 [maxk,10] 方便统计比较
print('转置 每行top-6 最大值下标',pred)

target_ = tf.broadcast_to(target, pred.shape) # target [10]广播成相同的形状 [maxk,10]
print('准确值',target_)
correct = tf.equal(pred, target_)
print(correct)
res = []
for k in topk:
# 分别计算top-1 到 top-k的准确率
correct_k = tf.cast(tf.reshape(correct[:k], [-1]), dtype=tf.float32)
# 展成行统计1的个数
correct_k = tf.reduce_sum(correct_k)
acc = float(correct_k* (100.0 / batch_size) )
res.append(acc)

return res

1
2
3
4
5
6
7
8
9
10
11
output = tf.random.normal([10, 6])
output = tf.math.softmax(output, axis=1) # 使得每行概率之和为1
target = tf.random.uniform([10], maxval=6, dtype=tf.int32) # 生成6类样本 因此top-6准确率一定为100%
print('prob:', output.numpy())

pred = tf.argmax(output, axis=1) # argmax() 每行最大值的索引
print('pred:', pred.numpy())
print('label:', target.numpy())

acc = accuracy(output, target, topk=(1,2,3,4,5,6))
print('\ntop-1-6 acc:', acc)
prob: [[0.22184627 0.1221462  0.07409586 0.34996933 0.07511458 0.15682773]
 [0.14504947 0.04924896 0.21993972 0.07217006 0.08854685 0.42504498]
 [0.1542809  0.14255568 0.07593964 0.09910513 0.395387   0.13273162]
 [0.16668463 0.11025342 0.11436021 0.03997175 0.28128707 0.28744298]
 [0.05896802 0.02670637 0.3851833  0.13821954 0.27897805 0.11194469]
 [0.16363983 0.24467127 0.08584066 0.08326607 0.3861453  0.03643688]
 [0.28560603 0.22363636 0.06274495 0.26323685 0.03589749 0.12887837]
 [0.38431036 0.09477527 0.1130109  0.0730463  0.15465215 0.18020503]
 [0.05116006 0.15413527 0.16139452 0.32532734 0.14692572 0.16105707]
 [0.10868432 0.05033949 0.30445468 0.13251573 0.3949189  0.00908681]]
pred: [3 5 4 5 2 4 0 0 3 4]
label: [1 3 5 2 1 0 4 4 1 1]
每行top-6 最大值下标 tf.Tensor(
[[3 0 5 1 4 2]
 [5 2 0 4 3 1]
 [4 0 1 5 3 2]
 [5 4 0 2 1 3]
 [2 4 3 5 0 1]
 [4 1 0 2 3 5]
 [0 3 1 5 2 4]
 [0 5 4 2 1 3]
 [3 2 5 1 4 0]
 [4 2 3 0 1 5]], shape=(10, 6), dtype=int32)
转置 每行top-6 最大值下标 tf.Tensor(
[[3 5 4 5 2 4 0 0 3 4]
 [0 2 0 4 4 1 3 5 2 2]
 [5 0 1 0 3 0 1 4 5 3]
 [1 4 5 2 5 2 5 2 1 0]
 [4 3 3 1 0 3 2 1 4 1]
 [2 1 2 3 1 5 4 3 0 5]], shape=(6, 10), dtype=int32)
准确值 tf.Tensor(
[[1 3 5 2 1 0 4 4 1 1]
 [1 3 5 2 1 0 4 4 1 1]
 [1 3 5 2 1 0 4 4 1 1]
 [1 3 5 2 1 0 4 4 1 1]
 [1 3 5 2 1 0 4 4 1 1]
 [1 3 5 2 1 0 4 4 1 1]], shape=(6, 10), dtype=int32)
tf.Tensor(
[[False False False False False False False False False False]
 [False False False False False False False False False False]
 [False False False False False  True False  True False False]
 [ True False  True  True False False False False  True False]
 [False  True False False False False False False False  True]
 [False False False False  True False  True False False False]], shape=(6, 10), dtype=bool)

top-1-6 acc: [0.0, 0.0, 20.0, 60.0, 80.0, 100.0]