Создание пользовательских метрик в оценщиках tensorflow

#tensorflow #tensorflow-estimator

#tensorflow #tensorflow-оценщик

Вопрос:

Я обучаю задачу классификации с использованием оценок тензорного потока.

Я хочу рассчитать оценку 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 должно быть двумя значениями, аналогичными точности и отзыву.

Может кто-нибудь, пожалуйста, помочь мне, как это сделать в оценщиках тензорного потока?

Ответ №1:

Прежде всего, TensorFlow имеет собственную оценку f1 tf.contrib.metrics.f1_score , и она довольно проста в использовании. Единственным возможным недостатком является то, что он скрывает пороговое значение от пользователя, выбирая наилучшее из указанного количества возможных пороговых значений.

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

Если по какой-либо причине вам нужна пользовательская реализация, вам необходимо сгруппировать update_ops . Каждая метрика тензорного потока имеет операцию, которая увеличивает ее значение. Вы можете установить пороговое значение вручную при определении прогнозов

 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

Комментарии:

1. Спасибо,,, я попробую

2. Это работает,,, Большое спасибо… Мне не хватало шага tf.group

3. обнаружена ошибка … оценка fscore регистрируется правильно, но обучение не … выдает ошибку.

4. TypeError: Expected float32, got <tf.Operation 'fscore' type=NoOp> of type 'Operation' instead

5. Очевидно, вы где-то передали операцию вместо значения. пожалуйста, обновите свой ответ соответствующим кодом.