在张量流估算器中创建自定义指标

Creating custom metrics in tensorflow estimators

我正在使用张量流估计器训练分类问题。

我想计算每批数据的 f1 分数以及精确率和召回率。

我使用下面的代码计算准确率和召回率,并将它们记录下来以供评估和训练。

我也使用公式计算 fscore,但在记录 fscore 时出现错误。

pre = tf.metrics.precision(labels=labels,predictions=pred,name="precision")

rec = tf.metrics.recall(labels=labels,predictions=pred,name="recall")

fscore_val = tf.reduce_mean((2*pre[0]*rec[0]) / (pre[0] + rec[0] + 1e-5))
fscore_update = tf.group(pre[1], rec[1])

fscore = (fscore_val, fscore_update)

# logging metric at evaluation time
metrics['precision'] = pre                    
metrics['recall'] = rec
metrics['fscore'] = fscore 

# logging metric at training time                   
tf.summary.scalar('precision', pre[1])
tf.summary.scalar('recall', rec[1])
tf.summary.scalar('fscore', fscore)


这是我得到的错误。

TypeError: Expected float32, got <tf.Operation 'metrics_Left_Lane_Type/group_deps' type=NoOp> of type 'Operation' instead.

我明白为什么会收到此错误。 因为fscore应该是两个值,类似于precision和recall。

有人可以帮助我了解如何在 tensorflow 估算器中执行此操作吗?

首先,TensorFlow 有自己的 f1 分数 tf.contrib.metrics.f1_score,而且使用起来相当简单。唯一可能的缺点是它对用户隐藏了阈值,从指定数量的可能阈值中选择最佳值。

predictions = tf.sigmoid(logits)
tf.contrib.metrics.f1_score(labels, predictions, num_thresholds=20)

如果出于任何原因您想要自定义实现,则需要分组 update_ops。每个 TensorFlow 指标都有增加其值的操作。您可以在定义预测时手动设置阈值

predictions = tf.greater(tf.sigmoid(logits), 0.5)
def f1_score(labels, predictions):
    precision, update_op_precision = tf.metrics.precision(labels, predictions)
    recall, update_op_recall = tf.metrics.recall(labels, predictions)
    eps = 1e-5 #small constant for numerical stability
    f1 = 2 * precision * recall / (precision + recall + eps)
    f1_upd = 2 * update_op_precision * update_op_recall / (update_op_precision + update_op_recall + eps)
    return f1, f1_upd

f1_score = f1_score(labels, predictions)

然后你可以将它添加到 eval_metric_ops dict 或传递给 summary.scalar

eval_metric_ops = {'f1': f1_score}
tf.summary.scalar('f1', f1_score[1])

它实际上给出了与来自 contrib 模块的指标非常接近的结果