Exportar gráficos de Tensorflow de Python para usar en C ++

¿Exactamente cómo deben exportarse los modelos de Python para su uso en c ++?

Estoy tratando de hacer algo similar a este tutorial: https://www.tensorflow.org/versions/r0.8/tutorials/image_recognition/index.html

Estoy intentando importar mi propio modelo de TF en la API de c ++ en lugar del modelo inicial. Ajusté el tamaño de entrada y las rutas, pero siguen apareciendo errores extraños. Pasé todo el día leyendo el desbordamiento de stack y otros foros, pero fue en vano.

He intentado dos métodos para exportar el gráfico.

Método 1: metagraph.

...loading inputs, setting up the model, etc.... sess = tf.InteractiveSession() sess.run(tf.initialize_all_variables()) for i in range(num_steps): x_batch, y_batch = batch(50) if i%10 == 0: train_accuracy = accuracy.eval(feed_dict={ x:x_batch, y_: y_batch, keep_prob: 1.0}) print("step %d, training accuracy %g"%(i, train_accuracy)) train_step.run(feed_dict={x: x_batch, y_: y_batch, keep_prob: 0.5}) print("test accuracy %g"%accuracy.eval(feed_dict={ x: features_test, y_: labels_test, keep_prob: 1.0})) saver = tf.train.Saver(tf.all_variables()) checkpoint = '/home/sander/tensorflow/tensorflow/examples/cat_face/data/model.ckpt' saver.save(sess, checkpoint) tf.train.export_meta_graph(filename= '/home/sander/tensorflow/tensorflow/examples/cat_face/data/cat_graph.pb', meta_info_def=None, graph_def=sess.graph_def, saver_def=saver.restre(sess, checkpoint), collection_list=None, as_text=False) 

El método 1 produce el siguiente error al intentar ejecutar el progtwig:

 [libprotobuf ERROR google/protobuf/src/google/protobuf/wire_format_lite.cc:532] String field 'tensorflow.NodeDef.op' contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes. E tensorflow/examples/cat_face/main.cc:281] Not found: Failed to load compute graph at 'tensorflow/examples/cat_face/data/cat_graph.pb' 

También probé otro método para exportar la gráfica:

Método 2: write_graph:

 tf.train.write_graph(sess.graph_def, '/home/sander/tensorflow/tensorflow/examples/cat_face/data/', 'cat_graph.pb', as_text=False) 

Esta versión realmente parece cargar algo, pero recibo un error acerca de las variables que no se están inicializando:

 Running model failed: Failed precondition: Attempting to use uninitialized value weight1 [[Node: weight1/read = Identity[T=DT_FLOAT, _class=["loc:@weight1"], _device="/job:localhost/replica:0/task:0/cpu:0"](weight1)]] 

Al principio, necesitas graficar la definición para archivar usando el siguiente comando

 with tf.Session() as sess: //Build network here tf.train.write_graph(sess.graph.as_graph_def(), "C:\\output\\", "mymodel.pb") 

Luego, guarde su modelo usando el protector

 saver = tf.train.Saver(tf.global_variables()) saver.save(sess, "C:\\output\\mymodel.ckpt") 

Luego, tendrás 2 archivos en tu salida, mymodel.ckpt, mymodel.pb

Descargue freeze_graph.py desde aquí y ejecute el siguiente comando en C: \ output \. Cambie el nombre del nodo de salida si es diferente para usted.

python freeze_graph.py –input_graph mymodel.pb –input_checkpoint mymodel.ckpt –output_node_names softmax / Reshape_1 –output_graph mymodelforc.pb

Puedes usar mymodelforc.pb directamente desde C.

Puedes usar el siguiente código C para cargar el archivo proto

 #include "tensorflow/core/public/session.h" #include "tensorflow/core/platform/env.h" #include "tensorflow/cc/ops/image_ops.h" Session* session; NewSession(SessionOptions(), &session); GraphDef graph_def; ReadBinaryProto(Env::Default(), "C:\\output\\mymodelforc.pb", &graph_def); session->Create(graph_def); 

Ahora puedes usar la sesión por inferencia.

Puede aplicar el parámetro de inferencia de la siguiente manera:

 // Same dimension and type as input of your network tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({ 1, height, width, channel })); std::vector finalOutput; // Fill input tensor with your input data std::string InputName = "input"; // Your input placeholder's name std::string OutputName = "softmax/Reshape_1"; // Your output placeholder's name session->Run({ { InputName, input_tensor } }, { OutputName }, {}, &finalOutput); // finalOutput will contain the inference output that you search for 

Puedes probar esto (modificar el nombre de la capa de salida):

 import os import tensorflow as tf from tensorflow.python.framework import graph_util def load_graph_def(model_path, sess=None): sess = sess if sess is not None else tf.get_default_session() saver = tf.train.import_meta_graph(model_path + '.meta') saver.restre(sess, model_path) def freeze_graph(sess, output_layer_name, output_graph): graph = tf.get_default_graph() input_graph_def = graph.as_graph_def() # Exporting the graph print("Exporting graph...") output_graph_def = graph_util.convert_variables_to_constants( sess, input_graph_def, output_layer_name.split(",")) with tf.gfile.GFile(output_graph, "wb") as f: f.write(output_graph_def.SerializeToString()) def freeze_from_checkpoint(checkpoint_file, output_layer_name): model_folder = os.path.basename(checkpoint_file) output_graph = os.path.join(model_folder, checkpoint_file + '.pb') with tf.Session() as sess: load_graph_def(checkpoint_file) freeze_graph(sess, output_layer_name, output_graph) if __name__ == '__main__': freeze_from_checkpoint( checkpoint_file='/home/sander/tensorflow/tensorflow/examples/cat_face/data/model.ckpt', output_layer_name='???')