首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于tensorflow流度量的自定义度量返回NaN

基于tensorflow流度量的自定义度量返回NaN
EN

Stack Overflow用户
提问于 2017-06-26 16:51:56
回答 2查看 3.6K关注 0票数 12

在TensorFlow中,我试图将F1分数定义为DNNClassifier的自定义度量。为此,我编写了一个函数

代码语言:javascript
复制
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)

它使用streaming_precision和TensorFlow中的streaming_recall来计算F1分数。在此之后,我为validation_metrics做了一个新的条目:

代码语言:javascript
复制
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)
}

然而,尽管我得到了正确的精度和召回值,f1score始终是nan

代码语言:javascript
复制
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

我的metric_fn出了点问题,但我想不出来。PRmetric_fn得到的值为Tensor("precision/value:0", shape=(), dtype=float32)形式。我觉得有点奇怪。我在期待一个标量张量。

任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-05 20:59:59

我认为问题可能来自于这样一个事实:您在metric_fn中使用的流度量没有得到任何更新。

尝试以下几点(我还包括了对我口味的一些小修改):

代码语言:javascript
复制
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))
票数 12
EN

Stack Overflow用户

发布于 2017-07-12 11:25:42

tf.learn.MetricSpec __init__的第一个论点是metric_fn

文件上说:

metric_fn:用作度量的函数。有关预测、标签和权重如何传递给此函数的规则,请参见_adapt_metric_fn。这必须返回单个张量(它被解释为此度量的值)或一对( value_op,update_op),其中value_op是要调用以获取度量值的op,并且应该为每个批处理运行update_op来更新内部状态。

由于您希望在metric_fn中使用流操作,所以不能返回单个张量,但必须考虑到流操作具有必须更新的内部状态。

因此,metric_fn的第一部分应该是:

代码语言:javascript
复制
def metric_fn(predictions=[], labels=[], weights=[]):
    P, update_precision = tf.contrib.metrics.streaming_precision(predictions, labels)
    R, update_recall = tf.contrib.metrics.streaming_recall(predictions, labels)

然后,如果您想在满足条件时返回0,就不能使用python if语句(这在tensorflow图中没有计算),但是您必须使用tf.cond (图中的计算)。

此外,您希望在更新操作(否则,第一个值是未定义的或P )之后,只检查R的值。

若要强制在tf.condR更新后对R进行计算,可以使用tf.control_dependencies

代码语言:javascript
复制
def metric_fn(predictions=[], labels=[], weights=[]):
    P, update_precision = tf.contrib.metrics.streaming_precision(predictions, labels)
    R, update_recall = tf.contrib.metrics.streaming_recall(predictions, labels)

    with tf.control_dependencies([P, update_precision, R, update_recall]):
        score = tf.cond(tf.equal(P + R, 0.), lambda: 0, lambda: 2*(P*R)/(P+R))
    return score, tf.group(update_precision, update_recall)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44764688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档