【问题标题】:how can I calculate the multi-label top k precisions with tensorflow?如何使用 tensorflow 计算多标签前 k 精度?
【发布时间】:2017-11-08 07:17:41
【问题描述】:

我的任务是预测一个句子中最可能出现的五个标签。现在我从输出(密集连接)层得到了未缩放的 logits:

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中,我应该用什么形式来完成这个任务呢?

【问题讨论】:

    标签: python tensorflow multilabel-classification


    【解决方案1】:

    解决方案

    我已经编写了一个如何执行计算的示例。此示例中的所有输入都被编码为 tf.constant ,但当然您可以替换您的变量。

    主要技巧是矩阵乘法。首先是 input_y 重新装入为2d矩阵(称为 to_top5 )。第二个是 corrict_preds 加权_matrix

    代码 h1>
    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"
    

    输出 h1>
    =============
    
    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的一切。

    【讨论】:

    • 当y_label是[1,num_classes]时,它适用,但是当涉及[batch_size,num_classes] IE [[12,31,3]的形状,[[12,31,3],[1,33,41] ],它似乎不起作用.. span>
    • 你误解了。我已经更新了问题,以突出显示代码已经处理了可变批处理大小。 span>
    • 灵感来自您的代码和使用重塑和乘法的想法,我通过张力扁平和tf.gather制作它,非常感谢! span>
    【解决方案2】:

    受@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]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-12
      • 2020-12-30
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      相关资源
      最近更新 更多