在张量流估算器中创建自定义指标
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 模块的指标非常接近的结果
我正在使用张量流估计器训练分类问题。
我想计算每批数据的 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 模块的指标非常接近的结果