簡體   English   中英

自定義 TensorFlow 指標:給定假陽性率下的真陽性率

[英]Custom TensorFlow metric: true positive rate at given false positive rate

我有一個二元分類問題,類別背景 (bg) = 0,信號 (sig) = 1,我正在為此訓練 NN。 出於監控目的,我正在嘗試使用 TensorFlow 后端在 Keras 中實現自定義指標,該指標執行以下操作:

1) 計算我的 NN 輸出的閾值,這將導致 X 的誤報率(將 bg 分類為信號)(在這種情況下 X = 0.02,但它可以是任何東西)。

2)計算這個閾值的真陽性率。

給定 numpy 數組 y_true, y_pred,我會寫一個函數,如:

def eff_at_2percent_metric(y_true, y_pred):
    #Find list of bg events
    bg_list = np.argwhere(y_true < 0.5)
    #Order by the NN output
    ordered_bg_predictions = np.flip(np.sort(y_pred[bg_list]),axis=0)
    #Find the threshold with 2% false positive rate
    threshold = ordered_bg_predictions[0.02*round(len(ordered_bg_list))]

    #Find list of signal events
    sig_list = np.argwhere(y_true > 0.5)
    #Order these by NN output
    ordered_sig_predictions = np.sort(y_pred[sig_list])
    #Find true positive rate with this threshold
    sig_eff = 1 - np.searchsorted(ordered_sig_predictions,threshold)/len(ordered_sig_predictions)

    return sig_eff

當然,這不起作用,因為要實現自定義指標,y_true 和 y_pred 應該是 TensorFlow 張量而不是 numpy 數組。 有什么辦法可以使這項工作正常進行嗎?

有一個針對特異性的敏感性指標,我認為它是等效的(特異性是 1 減去 FPR)。

您可以實現自己的指標,以下是誤報率的示例:

from tensorflow.python.eager import context
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import variable_scope
from tensorflow.python.ops.metrics_impl import _aggregate_across_towers
from tensorflow.python.ops.metrics_impl import true_negatives
from tensorflow.python.ops.metrics_impl import false_positives
from tensorflow.python.ops.metrics_impl import _remove_squeezable_dimensions

def false_positive_rate(labels,                                                             
               predictions,                                                     
               weights=None,                                                       
               metrics_collections=None,                                           
               updates_collections=None,                                           
               name=None):                                                         
  if context.executing_eagerly():                                                  
    raise RuntimeError('tf.metrics.recall is not supported is not '                
                       'supported when eager execution is enabled.')               
                                                                                   
  with variable_scope.variable_scope(name, 'false_alarm',                          
                                     (predictions, labels, weights)):           
    predictions, labels, weights = _remove_squeezable_dimensions(                  
        predictions=math_ops.cast(predictions, dtype=dtypes.bool),                 
        labels=math_ops.cast(labels, dtype=dtypes.bool),                           
        weights=weights)                                                           
                                                                                   
    false_p, false_positives_update_op = false_positives(                          
        labels,                                                                    
        predictions,                                                            
        weights,                                                                   
        metrics_collections=None,                                                  
        updates_collections=None,                                                  
        name=None)                                                                 
    true_n, true_negatives_update_op = true_negatives(                          
        labels,                                                                    
        predictions,                                                               
        weights,                                                                   
        metrics_collections=None,                                                  
        updates_collections=None,                                                  
        name=None)                                                              
                                                                                   
    def compute_false_positive_rate(true_n, false_p, name):                                        
      return array_ops.where(                                                      
          math_ops.greater(true_n + false_p, 0),                                   
          math_ops.div(false_p, true_n + false_p), 0, name)                        
                                                                                   
    def once_across_towers(_, true_n, false_p):                                 
      return compute_false_positive_rate(true_n, false_p, 'value')                              
                                                                                   
    false_positive_rate = _aggregate_across_towers(                                                
        metrics_collections, once_across_towers, true_n, false_p)                  
                                                                                   
    update_op = compute_false_positive_rate(true_negatives_update_op,                              
                               false_positives_update_op, 'update_op')             
    if updates_collections:                                                        
      ops.add_to_collections(updates_collections, update_op)                       
                                                                                   
    return false_positive_rate, update_op

您可以將代碼調整為真陽性率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM