Intercambie una tubería de entrada del conjunto de datos TensorFlow con un marcador de posición después del entrenamiento

Estoy trabajando con la nueva API tf.data.Dataset y parece que no puedo averiguar cómo realizar la inferencia. En última instancia, quiero convertir mi modelo a un gráfico TensorRT y ejecutarlo en el TX2, y todos los ejemplos que he encontrado suponen que tiene un tf.placeholder para la entrada. Aquí está el pseudocódigo de cómo estoy entrenando. El […] solo debe ser un marcador de posición ya que en realidad no ejecuté el código. No debatamos el modelo, ya que se supone que debemos dar un ejemplo:

 import tensorflow as tf # Setup iterator datain = tf.data.FixedLengthRecordDataset(datafiles, record_bytes1) labels = tf.data.FixedLengthRecordDataset(labelfiles, record_bytes2) dataset = tf.data.Dataset.zip((datain, labels)) dataset = dataset.prefetch(batch_size) dataset = dataset.repeat(n_epoch) iterator = dataset.make_initializable_iterator() sess = tf.Session() sess.run(iterator.initializer) [batch_x, batch_y] = iterator.get_next() # Define model function (let's not debate model except as relevant to question) def model_fn(xin): x0 = tf.transpose(tf.reshape(xin, [...], name='input')) w = tf.Variable(tf.truncated_normal([...], stddev=0.1)) x1 = tf.nn.conv2d(x0, w, strides=[...], padding='VALID') b = tf.Variable(tf.constant(0.0, shape=[...])) x2 = tf.nn.bias_add(x1, b) x3 = tf.nn.relu(x2, name='output') return x3 # Setup training environment model = model_fn(batch_x) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=model, labels=batch_y)) optimizer = tf.train.AdamOptimizer(learning_rate=1e-3).minimize(loss) # Train Model while True: try: sess.run(optimizer) except tf.errors.OutOfRangeError: break # Save model saver = tf.train.Saver(name='saver') saver.save(sess, 'temp/path') 

Mi pregunta es ¿cómo puedo obtener esto en TensorRT sin que la entrada sea un tf.placeholder ? Todo el ejemplo que puedo encontrar usa un tf.placeholder como entrada. Este ejemplo sugiere que puedo reemplazar el iterador con un marcador de posición usando la clase SavedModel , pero parece que no puedo encontrar ninguna documentación sobre cómo lograrlo.

¡Gracias!

EDITAR: Aquí está mi solución gracias a la ayuda de abajo

 from tensorflow.python.tools import optimize_for_inference_lib import uff # You can feed data to the IteratorGetNext node using feed_dict input_node_name = 'iterator_scope_name/IteratorGetNext' output_node_name = 'model_scope_name/output' # Run inference on the trained model: graph = tf.get_default_graph() batch_x = graph.get_tensor_by_name(input_node_name + ':0') networkout = graph.get_tensor_by_name(output_node_name + ':0') testdata, testlabel = custom_data_reader_fn(data_folder) # This will evaluate the model label = sess.run(networkout, feed_dict={batch_x: testdata}) # Freeze model and create a UFF file: graph_def = graph.as_graph_def() # Convert the graph to a serialized pb frozen_graph_def = tf.graph_util.convert_variables_to_constants(sess, graph_def, [output_node_name]) opt_graph_def = optimize_for_inference_lib.optimize_for_inference( frozen_graph_def, [input_node_name], [output_node_name], tf.float32.as_datatype_enum) uff.from_tensorflow(opt_graph_def, [output_node_name], quiet=False, output_filename='opt_model.uff') 

eso escribirá un archivo UFF que TensorRT puede utilizar. Los mayores problemas que encontré fueron:

  1. No me di cuenta de que la operación tf.placeholder reemplazó el iterator con un tf.placeholder
  2. No sabía a qué nodo alimentar datos para evaluación: puede enviar datos al nodo IteratorGetNext

Dado que ya tiene un gráfico capacitado guardado en un punto de control, en teoría, la solución más sencilla para usted es exportar el gráfico de inferencia a través de optimize_for_inference .

Esta herramienta funciona tanto para gráficos ya congelados como para su caso, para gráficos con variables aún definidas. Suponiendo que vaya por el modo de gráfico congelado, el primer paso es transformar las variables de su gráfico en constantes a través de:

 python freeze_graph.py \ --input_graph=temp/path/graph.pbtxt \ --input_checkpoint=temp/path/your_model_name.ckpt \ --output_graph=frozen_model.pb \ --output_node_names=name_of_the_output_tensor_you_want_to_use 

Esto generará un nuevo archivo binario llamado frozen_model.pb que tiene las operaciones de Variable reemplazadas con Const ops con los valores cargados desde el archivo de punto de control.

Entonces, necesitas generar el gráfico de inferencia con:

 python optimize_for_inference.py \ --input=frozen_model.pb \ --output=inference.pb \ --frozen_graph=True \ --input_names=IteratorGetNext --output_names=name_of_the_output_tensor_you_want_to_use 

Esto reemplazará el nodo IteratorGetNext con un marcador de posición flotante. Es posible que desee elegir otro nodo, en cuyo caso simplemente cambie el nombre. También puede cambiar el tipo del marcador de posición generado a través de la opción --placeholder_type_enum . En ese caso, debe proporcionar un valor entero que coincida con el tipo de datos que desea de la enumeración DataType .

NOTA: Dije “en teoría” porque, en realidad, al inspeccionar el gráfico de inicio generado en una prueba que hice, parece que todavía hay algunas operaciones extrañas que no son realmente necesarias para la inferencia. Es posible que tenga que seguir procesando su gráfico a través de Graph Surgeon o la herramienta de transformación de gráficos de TF