我正在使用张量流估计器训练分类问题。
我想计算每批数据的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。
有人可以在张量估计中帮助我吗?
答案 0 :(得分:1)
首先,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
字典或传递给summary.scalar
eval_metric_ops = {'f1': f1_score}
tf.summary.scalar('f1', f1_score[1])
使用contrib模块的指标,它实际上给出了非常接近的结果