TypeError: no se puede llamar con soporte utilizando Dataset con estimator input_fn

Estoy tratando de convertir el tutorial de Iris ( https://www.tensorflow.org/get_started/estimator ) para leer los datos de entrenamiento de los archivos .png en lugar de .csv. Funciona con numpy_input_fn pero no cuando lo hago desde un Dataset . Creo que input_fn() está devolviendo el tipo incorrecto pero realmente no entiendo lo que debería ser y cómo hacerlo. El error es:

  File "iris_minimal.py", line 27, in  model_fn().train(input_fn(), steps=1) ... raise TypeError('unsupported callable') from ex TypeError: unsupported callable 

La versión de TensorFlow es 1.3. Código completo:

 import tensorflow as tf from tensorflow.contrib.data import Dataset, Iterator NUM_CLASSES = 3 def model_fn(): feature_columns = [tf.feature_column.numeric_column("x", shape=[4])] return tf.estimator.DNNClassifier([10, 20, 10], feature_columns, "tmp/iris_model", NUM_CLASSES) def input_parser(img_path, label): one_hot = tf.one_hot(label, NUM_CLASSES) file_contents = tf.read_file(img_path) image_decoded = tf.image.decode_png(file_contents, channels=1) image_decoded = tf.image.resize_images(image_decoded, [2, 2]) image_decoded = tf.reshape(image_decoded, [4]) return image_decoded, one_hot def input_fn(): filenames = tf.constant(['images/image_1.png', 'images/image_2.png']) labels = tf.constant([0,1]) data = Dataset.from_tensor_slices((filenames, labels)) data = data.map(input_parser) iterator = data.make_one_shot_iterator() features, labels = iterator.get_next() return features, labels model_fn().train(input_fn(), steps=1) 

He notado varios errores en tu fragmento de código:

  • train método de train acepta la función de entrada, por lo que debe ser input_fn , no input_fn() .
  • Las características se esperan como un diccionario, por ejemplo, {'x': features} .
  • DNNClassifier utiliza la función de pérdida SparseSoftmaxCrossEntropyWithLogits . Sparse significa que asume la representación de la clase ordinal, en lugar de uno-caliente, por lo que su conversión es innecesaria ( esta pregunta explica la diferencia entre las pérdidas de entropía cruzada en tf).

Intente este código a continuación:

 import tensorflow as tf from tensorflow.contrib.data import Dataset NUM_CLASSES = 3 def model_fn(): feature_columns = [tf.feature_column.numeric_column("x", shape=[4], dtype=tf.float32)] return tf.estimator.DNNClassifier([10, 20, 10], feature_columns, "tmp/iris_model", NUM_CLASSES) def input_parser(img_path, label): file_contents = tf.read_file(img_path) image_decoded = tf.image.decode_png(file_contents, channels=1) image_decoded = tf.image.resize_images(image_decoded, [2, 2]) image_decoded = tf.reshape(image_decoded, [4]) label = tf.reshape(label, [1]) return image_decoded, label def input_fn(): filenames = tf.constant(['input1.jpg', 'input2.jpg']) labels = tf.constant([0,1], dtype=tf.int32) data = Dataset.from_tensor_slices((filenames, labels)) data = data.map(input_parser) data = data.batch(1) iterator = data.make_one_shot_iterator() features, labels = iterator.get_next() return {'x': features}, labels model_fn().train(input_fn, steps=1)