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:
tf.placeholder
reemplazó el iterator
con un tf.placeholder
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