Вычислить F1 балл, используя tf.metrics.precision / отзыва в настройке tf.Estimator - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь вычислить оценку F1 в настройке tf.Estimator.

Я видел этот ТАК вопрос , но не смог отобрать рабочее решение из него.

С 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

Ответы [ 2 ]

0 голосов
/ 15 июля 2019

Тензор значения f1 может быть вычислен из значений точности и возврата.Метрики должны быть (value, update_op) кортежами.Мы можем передать идентичность для f1.Это сработало для меня:

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))
    }
0 голосов
/ 04 декабря 2018

1) Почему вы делаете tf.metrics.mean?Вызов и точность являются скалярными значениями

2) Вы пробовали печатать f1_score и f1_update_op?

3) Из документации отзыва они упоминают, как

Для оценки метрики по потоку данных функция создает update_op, который обновляет эти переменные и возвращает отзыв.update_op взвешивает каждое предсказание по соответствующему значению в весах

Поскольку вы получаете оценку F1 непосредственно от двух операций, выполняющих обновление, попробуйте выполнить tf.identity (который фактически не вызывает изменений)

...