基于tensorflow的流量指标的自定义指标返回NaN

The*_*Lad 12 python tensorflow

我试图在TensorFlow中将F1得分定义为自定义指标DNNClassifier.为此,我写了一个函数

def metric_fn(predictions=[], labels=[], weights=[]):
    P, _ = tf.contrib.metrics.streaming_precision(predictions, labels)
    R, _ = tf.contrib.metrics.streaming_recall(predictions, labels)
    if P + R == 0:
        return 0
    return 2*(P*R)/(P+R)
Run Code Online (Sandbox Code Playgroud)

使用streaming_precisionstreaming_recall来自TensorFlow来计算F1得分.之后,我为validation_metrics创建了一个新条目:

validation_metrics = {
    "accuracy":
        tf.contrib.learn.MetricSpec(
            metric_fn=tf.contrib.metrics.streaming_accuracy,
            prediction_key=tf.contrib.learn.PredictionKey.CLASSES),
    "precision":
        tf.contrib.learn.MetricSpec(
            metric_fn=tf.contrib.metrics.streaming_precision,
            prediction_key=tf.contrib.learn.PredictionKey.CLASSES),
    "recall":
        tf.contrib.learn.MetricSpec(
            metric_fn=tf.contrib.metrics.streaming_recall,
            prediction_key=tf.contrib.learn.PredictionKey.CLASSES),
    "f1score":
        tf.contrib.learn.MetricSpec(
            metric_fn=metric_fn,
            prediction_key=tf.contrib.learn.PredictionKey.CLASSES)
}
Run Code Online (Sandbox Code Playgroud)

但是,虽然我得到了正确的精度和召回值,但f1score总是nan:

INFO:tensorflow:Saving dict for global step 151: accuracy = 0.982456, accuracy/baseline_label_mean = 0.397661, accuracy/threshold_0.500000_mean = 0.982456, auc = 0.982867, f1score = nan, global_step = 151, labels/actual_label_mean = 0.397661, labels/prediction_mean = 0.406118, loss = 0.310612, precision = 0.971014, precision/positive_threshold_0.500000_mean = 0.971014, recall = 0.985294, recall/positive_threshold_0.500000_mean = 0.985294
Run Code Online (Sandbox Code Playgroud)

我有些不对劲metric_fn,但我无法理解.的值PR所获得metric_fn的形式为 Tensor("precision/value:0", shape=(), dtype=float32).我觉得这有点奇怪.我期待一个标量张量.

任何帮助表示赞赏.

P-G*_*-Gn 11

我认为问题可能来自于您在其中使用的流量指标metric_fn未获得任何更新.

尝试以下(我还包括对我的口味的微小修改):

def metric_fn(predictions=None, labels=None, weights=None):
    P, update_op1 = tf.contrib.metrics.streaming_precision(predictions, labels)
    R, update_op2 = tf.contrib.metrics.streaming_recall(predictions, labels)
    eps = 1e-5;
    return (2*(P*R)/(P+R+eps), tf.group(update_op1, update_op2))
Run Code Online (Sandbox Code Playgroud)