我的任务是预测句子中五个最可能的标签。现在我从输出(密集连接)层获得了未缩放的日志:
with tf.name_scope("output"):
scores = tf.nn.xw_plus_b(self.h_drop, W,b, name="scores")
predictions = tf.nn.top_k(self.scores, 5) # should be the k highest score
with tf.name_scope("accuracy"):
labels = input_y # its shape is (batch_size, num_classes)
# calculate the top k accuracy
现在预测就像[3,1,2,50,12](3,1 ......是得分最高的索引),而标签是"多热"形式:[0,1,0,1,1,0 ...]。 在python中,我可以简单地写
correct_preds = [input_y[i]==1 for i in predictions]
weighted = np.dot(correct_preds, [5,4,3,2,1]) # weighted by rank
recall = sum(correct_preds) /sum(input_y)
precision =sum(correct_preds)/len(correct_preds)
但是在tensorflow中,我用什么形式来完成这项任务?
答案 0 :(得分:4)
我编写了一个如何进行计算的例子。此示例中的所有输入都编码为 tf.constant ,但您当然可以替换变量。
主要技巧是矩阵乘法。首先将 input_y 重新整形为[1x5]一个名为 to_top5 的矩阵的2d倍。第二个是 weighted_matrix correct_preds 。
import tensorflow as tf
input_y = tf.constant( [5,2,9,1] , dtype=tf.int32 )
predictions = tf.constant( [[9,3,5,2,1],[8,9,0,6,5],[1,9,3,4,5],[1,2,3,4,5]])
to_top5 = tf.constant( [[1,1,1,1,1]] , dtype=tf.int32 )
input_y_for_top5 = tf.matmul( tf.reshape(input_y,[-1,1]) , to_top5 )
correct_preds = tf.cast( tf.equal( input_y_for_top5 , predictions ) , dtype=tf.float16 )
weighted_matrix = tf.constant( [[5.],[4.],[3.],[2.],[1.]] , dtype=tf.float16 )
weighted = tf.matmul(correct_preds,weighted_matrix)
recall = tf.reduce_sum(correct_preds) / tf.cast( tf.reduce_sum(input_y) , tf.float16)
precision = tf.reduce_sum(correct_preds) / tf.constant(5.0,dtype=tf.float16)
## training
# Run tensorflow and print the result
with tf.Session() as sess:
print "\n\n=============\n\n"
print "\ninput_y_for_top5"
print sess.run(input_y_for_top5)
print "\ncorrect_preds"
print sess.run(correct_preds)
print "\nweighted"
print sess.run(weighted)
print "\nrecall"
print sess.run(recall)
print "\nprecision"
print sess.run(precision)
print "\n\n=============\n\n"
=============
input_y_for_top5
[[5 5 5 5 5]
[2 2 2 2 2]
[9 9 9 9 9]
[1 1 1 1 1]]
correct_preds
[[ 0. 0. 1. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 1. 0. 0. 0. 0.]]
weighted
[[ 3.]
[ 0.]
[ 4.]
[ 5.]]
recall
0.17651
precision
0.6001
=============
以上示例显示批次大小为4。
第一批 y_label 5 ,这意味着索引为5的元素是第一批的正确标签。此外,第一批的预测是[9,3,5,2,1],这意味着预测函数认为第9个元素最有可能,那么元素3是下一个最有可能的,依此类推。
假设我们想要一个批量大小为3的示例,然后使用以下代码
input_y = tf.constant( [5,2,9] , dtype=tf.int32 )
predictions = tf.constant( [[9,3,5,2,1],[8,9,0,6,5],[1,9,3,4,5]])
如果我们用上面的代码替换程序,我们可以看到它确实正确地计算了批量大小为3的所有内容。
答案 1 :(得分:1)
受上面@wontonimo回答的启发,我使用矩阵运算和tf.reshape,tf.gather实现了一个方法。标签张量是“多热的”,例如[[0,1,0,1],[1,0,0,1]。预测张量由tf.nn.top_k获得,看起来像[[3,1],[0,1]]。这是代码:
top_k_pred = tf.nn.top_k(logits, 5)
tmp1 = tf.reshape(tf.range(batch_size)*num_classes, (-1,1))
idx_incre = top_k_pred[1] + tf.concat([tmp1]*5,1)
correct_preds = tf.gather(tf.reshape(y_label, (-1,), tf.reshape(idx_incre, (-1,)))
correct_preds = tf.reshape(correct_pred, (batch_size, 5))
weighted = correct_preds * [[5],[4],[3],[2],[1]]