在 tf.Estimator 设置中使用 tf.metrics.precision/recall 计算 F1 分数
Calculate F1 Score using tf.metrics.precision/recall in a tf.Estimator setup
我正在尝试在 tf.Estimator
设置中计算 F1 分数。
我看过这个 ,但无法从中提炼出有效的解决方案。
tf.Estimator
的问题是它希望我提供一个值和一个更新操作,所以现在,我的模型末尾有这段代码:
if mode == tf.estimator.ModeKeys.EVAL:
with tf.variable_scope('eval'):
precision, precision_update_op = tf.metrics.precision(labels=labels,
predictions=predictions['class'],
name='precision')
recall, recall_update_op = tf.metrics.recall(labels=labels,
predictions=predictions['class'],
name='recall')
f1_score, f1_update_op = tf.metrics.mean((2 * precision * recall) / (precision + recall), name='f1_score')
eval_metric_ops = {
"precision": (precision, precision_update_op),
"recall": (recall, recall_update_op),
"f1_score": (f1_score, f1_update_op)}
现在准确率和召回率似乎都很好,但在 F1 分数上,我一直在 nan
。
我应该如何让它工作?
编辑:
可以使用 tf.contrib.metrics.f1_score
实现可行的解决方案,但由于 contrib
将在 TF 2.0 中弃用,我希望能有一个 contrib
更少的解决方案
1) 为什么要 tf.metrics.mean
?召回率和精度是标量值
2) 你试过打印 f1_score
和 f1_update_op
吗?
3) 从 documentation of recall 他们提到
For estimation of the metric over a stream of data, the function creates an update_op that updates these variables and returns the recall. update_op weights each prediction by the corresponding value in weights
由于您直接从处理更新的两个操作中获取 F1 分数,请尝试执行 tf.identity(这实际上不会导致任何更改)
可以根据精度和召回值计算 f1 值张量。指标必须是 (value, update_op) 元组。我们可以为 f1 传递 tf.identity。这对我有用:
import tensorflow as tf
def metric_fn(labels, logits):
predictions = tf.argmax(logits, axis=-1)
pr, pr_op = tf.metrics.precision(labels, predictions)
re, re_op = tf.metrics.recall(labels, predictions)
f1 = (2 * pr * re) / (pr + re)
return {
'precision': (pr, pr_op),
'recall': (re, re_op),
'f1': (f1, tf.identity(f1))
}
我是这样做的:
def f1_score_class0(labels, predictions):
"""
To calculate f1-score for the 1st class.
"""
prec, update_op1 = tf.compat.v1.metrics.precision_at_k(labels, predictions, 1, class_id=0)
rec, update_op2 = tf.compat.v1.metrics.recall_at_k(labels, predictions, 1, class_id=0)
return {
"f1_Score_for_class0":
( 2*(prec * rec) / (prec + rec) , tf.group(update_op1, update_op2) )
}
TensorFlow addons已经有官方解决方案
https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/F1Score
我正在尝试在 tf.Estimator
设置中计算 F1 分数。
我看过这个
tf.Estimator
的问题是它希望我提供一个值和一个更新操作,所以现在,我的模型末尾有这段代码:
if mode == tf.estimator.ModeKeys.EVAL:
with tf.variable_scope('eval'):
precision, precision_update_op = tf.metrics.precision(labels=labels,
predictions=predictions['class'],
name='precision')
recall, recall_update_op = tf.metrics.recall(labels=labels,
predictions=predictions['class'],
name='recall')
f1_score, f1_update_op = tf.metrics.mean((2 * precision * recall) / (precision + recall), name='f1_score')
eval_metric_ops = {
"precision": (precision, precision_update_op),
"recall": (recall, recall_update_op),
"f1_score": (f1_score, f1_update_op)}
现在准确率和召回率似乎都很好,但在 F1 分数上,我一直在 nan
。
我应该如何让它工作?
编辑:
可以使用 tf.contrib.metrics.f1_score
实现可行的解决方案,但由于 contrib
将在 TF 2.0 中弃用,我希望能有一个 contrib
更少的解决方案
1) 为什么要 tf.metrics.mean
?召回率和精度是标量值
2) 你试过打印 f1_score
和 f1_update_op
吗?
3) 从 documentation of recall 他们提到
For estimation of the metric over a stream of data, the function creates an update_op that updates these variables and returns the recall. update_op weights each prediction by the corresponding value in weights
由于您直接从处理更新的两个操作中获取 F1 分数,请尝试执行 tf.identity(这实际上不会导致任何更改)
可以根据精度和召回值计算 f1 值张量。指标必须是 (value, update_op) 元组。我们可以为 f1 传递 tf.identity。这对我有用:
import tensorflow as tf
def metric_fn(labels, logits):
predictions = tf.argmax(logits, axis=-1)
pr, pr_op = tf.metrics.precision(labels, predictions)
re, re_op = tf.metrics.recall(labels, predictions)
f1 = (2 * pr * re) / (pr + re)
return {
'precision': (pr, pr_op),
'recall': (re, re_op),
'f1': (f1, tf.identity(f1))
}
我是这样做的:
def f1_score_class0(labels, predictions):
"""
To calculate f1-score for the 1st class.
"""
prec, update_op1 = tf.compat.v1.metrics.precision_at_k(labels, predictions, 1, class_id=0)
rec, update_op2 = tf.compat.v1.metrics.recall_at_k(labels, predictions, 1, class_id=0)
return {
"f1_Score_for_class0":
( 2*(prec * rec) / (prec + rec) , tf.group(update_op1, update_op2) )
}
TensorFlow addons已经有官方解决方案
https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/F1Score