tf.constant y tf.placeholder se comportan de manera diferente

Quiero ajustar tf.metrics alrededor de un módulo de Sonnet para medir el rendimiento de cada lote, y lo siguiente es el trabajo que he hecho:

import tensorflow as tf import sonnet as snt class Metrics(snt.AbstractModule): def __init__(self, indicator, summaries = None, name = "metrics"): super(Metrics, self).__init__(name = name) self._indicator = indicator self._summaries = summaries def _build(self, labels, logits): if self._indicator == "accuracy": metric, metric_update = tf.metrics.accuracy(labels, logits) with tf.control_dependencies([metric_update]): outputs = tf.identity(metric) elif self._indicator == "precision": metric, metric_update = tf.metrics.precision(labels, logits) with tf.control_dependencies([metric_update]): outputs = tf.identity(metric) elif self._indicator == "recall": metric, metric_update = tf.metrics.recall(labels, logits) with tf.control_dependencies([metric_update]): outputs = tf.identity(metric) elif self._indicator == "f1_score": metric_recall, metric_update_recall = tf.metrics.recall(labels, logits) metric_precision, metric_update_precision = tf.metrics.precision(labels, logits) with tf.control_dependencies([metric_update_recall, metric_update_precision]): outputs = 2.0 / (1.0 / metric_recall + 1.0 / metric_precision) else: raise ValueError("unsupported metrics") if type(self._summaries) == list: self._summaries.append(tf.summary.scalar(self._indicator, outputs)) return outputs 

Sin embargo, cuando quiero probar el módulo, funciona el siguiente código:

 def test3(): import numpy as np labels = tf.constant([1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], tf.int32) logits = tf.constant([1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], tf.int32) metrics = Metrics("accuracy") accuracy = metrics(labels, logits) metrics2 = Metrics("f1_score") f1_score = metrics2(labels, logits) writer = tf.summary.FileWriter("utils-const", tf.get_default_graph()) with tf.Session() as sess: sess.run([tf.global_variables_initializer(), tf.local_variables_initializer()]) accu, f1 = sess.run([accuracy, f1_score]) print(accu) print(f1) writer.close() 

Sin embargo, el siguiente código NO funciona:

 def test4(): from tensorflow.python import debug as tf_debug import numpy as np tf_labels = tf.placeholder(dtype=tf.int32, shape=[None]) tf_logits = tf.placeholder(dtype=tf.int32, shape=[None]) labels = np.array([1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], np.int32) logits = np.array([1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], np.int32) metrics = Metrics("accuracy") accuracy = metrics(tf_labels, tf_logits) metrics2 = Metrics("f1_score") f1_score = metrics2(tf_labels, tf_logits) writer = tf.summary.FileWriter("utils-feed", tf.get_default_graph()) with tf.Session() as sess: sess.run([tf.global_variables_initializer(), tf.local_variables_initializer()]) sess = tf_debug.LocalCLIDebugWrapperSession(sess) accu, f1 = sess.run([accuracy, f1_score], feed_dict = {tf_labels: labels, tf_logits: logits}) print(accu) print(f1) writer.close() 

La salida de test3 () es correcta, 0.88. La salida de test4 () es incorrecta, 0.0. Sin embargo, deben ser equivalentes.

Alguien tiene alguna idea?

¿Está seguro de que no es la versión tf.constant que falla? Encuentro que tf.metrics tiene un comportamiento extraño en combinación con tf.constant :

 import tensorflow as tf a = tf.constant(1.) mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): mean_a = tf.identity(mean_a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run(mean_a)) 

devuelve, cuando se ejecuta en la GPU,

 0.0 2.0 1.5 1.3333334 1.25 1.2 1.1666666 1.1428572 1.125 1.1111112 

en lugar de 1 s. Parece que el conteo se está retrasando en uno. (Supongo que el primer valor sería inf pero es cero debido a algunas condiciones en el count ). Una versión de marcador de posición de este código se ejecuta como se espera, por otro lado.

En la CPU, el comportamiento es aún más raro, ya que la salida no es determinista. Ejemplo de salida:

 0.0 1.0 1.0 0.75 1.0 1.0 0.85714287 0.875 1.0 0.9 

Parece un error que podría iniciar sesión en el repository github de tensorflow . (Tenga en cuenta que usar métricas en ejecución en constantes no es útil, pero sigue siendo un error).

EDITAR Ahora también me topé con ejemplos extraños con un tf.placeholder , parece que tf.metrics tiene un error que desafortunadamente no se limita a su uso con tf.constant s.