Я пытаюсь понять, как агрегировать метрические переменные в Tensorflow, и наткнулся на tf.contrib.metrics.streaming_dynamic_auc
. Он агрегирует прогнозы и метки, что кажется простым, но меня озадачивает то, что первый запуск после инициализации дает 0, а все последующие запуски работают нормально. Вот код.
import tensorflow as tf
import random
random.seed(121231)
n_points = 1000
y_true = [random.randint(0, 1) for _ in xrange(n_points)]
y_pred = [random.random() for _ in xrange(n_points)]
pds = tf.placeholder(tf.float32, [n_points])
lbs = tf.placeholder(tf.int32, [n_points])
with tf.Session() as sess:
auc_dynamic = tf.contrib.metrics.streaming_dynamic_auc(predictions=pds, labels=lbs)
auc = tf.metrics.auc(predictions=pds, labels=lbs)
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
auc_dynamic_val, auc_dynamic_op = sess.run(auc_dynamic, {pds:y_pred, lbs:y_true})
auc_val, auc_op = sess.run(auc, {pds: y_pred, lbs: y_true})
print("1st run. Dynamic auc val %.7f, op: %s" % (auc_dynamic_val, auc_dynamic_op))
print("1st run. Auc val %.7f, op: %s" % (auc_val, auc_op))
auc_dynamic_val, auc_dynamic_op = sess.run(auc_dynamic, {pds: y_pred, lbs: y_true})
auc_val, auc_op = sess.run(auc, {pds: y_pred, lbs: y_true})
print("2nd run. Dynamic auc val %.7f, op: %s" % (auc_dynamic_val, auc_dynamic_op))
print("2nd run. Auc val %.7f, op: %s" % (auc_val, auc_op))
Он печатает:
1st run. Dynamic auc val 0.0000000, op: None
1st run. Auc val 0.0000000, op: 0.5043121
2nd run. Dynamic auc val 0.5043422, op: None
2nd run. Auc val 0.5043121, op: 0.5043121
Существует несоответствие между dynamic auc
и auc
Динамический аук op
всегда None
и его значение равно 0 при первом запуске. Однако при втором запуске значения совпадают.
Нет, это предполагаемое поведение. Метрики TF выводят кортеж со значением и обновляют операцию, это значение обновления. Таким образом, при первом запуске фактическое значение, первый вывод метрики будет равен 0. Если вы просто напечатаете оба значения два раза, вы увидите, что при втором запуске оба значения будут ненулевыми.
with tf.Session() as sess:
auc_tf = tf.contrib.metrics.streaming_dynamic_auc(predictions=pds, labels=lbs)
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
auc_tf_val = sess.run(auc_tf, {pds:y_pred, lbs:y_true})
print(auc_tf_val)
auc_tf_val = sess.run(auc_tf, {pds: y_pred, lbs: y_true})
print(auc_tf_val)
P.S. Я не знаю ваше конкретное приложение и версию TF, которую вы используете, но я думаю, что лучше использовать tf.metrics.auc
. Модуль Contrib будет объявлен устаревшим в будущих версиях.
https://www.tensorflow.org/api_docs/python/tf/metrics/auc
Обновлено: в отношении конкретного случая, упомянутого в вопросе. Значение update_op всегда равно None
, потому что оно вычисляется по-разному. В случае метрик модуля contrib это <class 'tensorflow.python.framework.ops.Operation'>
, в то время как модуль метрик возвращает простой тензор, который может быть оценен внутри сеанса, поэтому имеет значение.
Это зависит от того, где вы ищете. Тензорборд? Чтобы добавить туда резюме, вам нужно объединить их и написать с помощью tf.summary.FileWriter
Если вы запустите мой код и замените _
на auc_op
и посмотрите на него, это всегда будет None
. И добавление его в сводку приводит к ошибке. Также я использую довольно большую систему, основанную на CustomEstoimator
. У меня есть хуки для ведения журнала и хуки для сохранения сводных данных, оба выводят нули для этого конкретного auc. Аук по умолчанию работает нормально.
Это легко может быть вызвано данными. Попробуйте использовать его изолированно с некоторыми предопределенными константами в качестве логитов/меток.
Хм, не уверен, что понимаю. Если я использую приведенный выше код для печати auc_op
for tf.metrics.auc
, он будет иметь значения при каждом вызове. auc_op
ибо streaming_dynamic_auc
всегда есть None
. Как это связано с данными? Я использую одни и те же данные для обоих.
О, я понял. Обновленный ответ. Надеюсь, это прояснит
Хм, я думаю, ваши ответы проясняют ситуацию. Спасибо! Я подожду несколько дней и отмечу свой вопрос как отвеченный.
Я изучаю различные реализации aucs, не очень заинтересованы в их использовании. Другой вопрос, что его оп всегда
None
. И я не могу добавить его резюме. Если я это сделаюtf.summary.scalar('metrics_auc', auc_value)
, я получу только нули и не смогу добавить какtf.summary.scalar('metrics_auc', auc_op)
, потому чтоauc_op
этоNone
.