3

Я тренируюсь моделью и сохранить его с помощью:TensorFlow 0,12 Модели Файлы

saver = tf.train.Saver() 
saver.save(session, './my_model_name') 

Кроме контрольной точки файла, который просто содержит указатели на самом последние контрольные точки модели, это создает следующие 3 файлы текущий путь:

  1. my_model_name.meta
  2. my_model_name.index
  3. my_model_name.data-00000-оф-00001

Интересно, что каждый из этих файлов содержит.

Я хотел бы загрузить эту модель на C++ и выполнить вывод. Пример label_image загружает модель из одного файла .bp с использованием ReadBinaryProto(). Интересно, как я могу загрузить его из этих 3-х файлов. Что такое эквивалент C++ для следующего?

new_saver = tf.train.import_meta_graph('./my_model_name.meta') 
new_saver.restore(session, './my_model_name') 

ответ

2

Я в настоящее время борюсь с этим сам, я обнаружил, что в настоящее время это не так просто. Два наиболее часто цитируемые учебники по этому вопросу являются: https://medium.com/jim-fleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f#.goxwm1e5j и https://medium.com/@hamedmp/exporting-trained-tensorflow-models-to-c-the-right-way-cf24b609d183#.g1gak956i

Эквивалент

new_saver = tf.train.import_meta_graph('./my_model_name.meta') 
new_saver.restore(session, './my_model_name') 

Есть только

Status load_graph_status = LoadGraph(graph_path, &session); 

Предполагая, что вы "заморожен граф" (Используется скрипт, который объединяет файл графа с значениями контрольной точки). Также см. Обсуждение здесь: Tensorflow Different ways to Export and Run graph in C++

+0

Спасибо, @Ian. Я также нашел это: https://blog.metaflow.fr/tensorflow-how-to-freeze-a-model-and-serve-it-with-a-python-api-d4f3596b3adc#.ay0m5hj9k – mhaghighat

+0

Хорошая находка. Кажется, что они делают то, что мы пытаемся сделать, но только с Python, а не с C++. В настоящее время я просматриваю эту проблему: https://github.com/tensorflow/tensorflow/issues/615 Что породил этот вопрос: http://stackoverflow.com/questions/35508866/tensorflow-different-ways-to-export -and-run-graph-in-c –

+0

Вы, ребята, наконец-то добились успеха? Я также борюсь с этим, я пробовал много разных методов, но большинство из них не могут сохранить значения переменных, другие сбой или дать мне постоянный вывод в C++ ... http://stackoverflow.com/questions/43515671/tensorflow-freeze-graph-does-not-store-the-variable-values ​​ – gdelab

4

То, что создает ваша заставка, называется «Checkpoint V2» и было введено в TF 0.12.

У меня это работает очень хорошо (хотя документы на C++-странице ужасны, поэтому мне потребовался день, чтобы решить). Некоторые люди предлагают converting all variables to constants или freezing the graph, но ни один из них на самом деле не нужен.

Python часть (экономия)

with tf.Session() as sess: 
    tf.train.Saver(tf.trainable_variables()).save(sess, 'models/my-model') 

Если вы создаете Saver с tf.trainable_variables(), вы можете сэкономить некоторую головную боль и место для хранения. Но, возможно, некоторым более сложным моделям нужны все данные для сохранения, затем удалите этот аргумент до Saver, просто убедитесь, что вы создаете Saverпосле, ваш график создан. Также очень важно дать всем переменным/слоям уникальные имена, иначе вы можете запускать разные задачи.

C++ часть (умозаключение)

Обратите внимание, что checkpointPath не путь к какой-либо из существующих файлов, только их общий префикс. Если вы по ошибке поместите туда путь к файлу .index, TF не скажет вам, что это было неправильно, но он умрет во время вывода из-за неинициализированных переменных.

#include <tensorflow/core/public/session.h> 
#include <tensorflow/core/protobuf/meta_graph.pb.h> 

using namespace std; 
using namespace tensorflow; 

... 
// set up your input paths 
const string pathToGraph = "models/my-model.meta" 
const string checkpointPath = "models/my-model"; 
... 

auto session = NewSession(SessionOptions()); 
if (session == nullptr) { 
    throw runtime_error("Could not create Tensorflow session."); 
} 

Status status; 

// Read in the protobuf graph we exported 
MetaGraphDef graph_def; 
status = ReadBinaryProto(Env::Default(), pathToGraph, &graph_def); 
if (!status.ok()) { 
    throw runtime_error("Error reading graph definition from " + pathToGraph + ": " + status.ToString()); 
} 

// Add the graph to the session 
status = session->Create(graph_def.graph_def()); 
if (!status.ok()) { 
    throw runtime_error("Error creating graph: " + status.ToString()); 
} 

// Read weights from the saved checkpoint 
Tensor checkpointPathTensor(DT_STRING, TensorShape()); 
checkpointPathTensor.scalar<std::string>()() = checkpointPath; 
status = session->Run(
     {{ graph_def.saver_def().filename_tensor_name(), checkpointPathTensor },}, 
     {}, 
     {graph_def.saver_def().restore_op_name()}, 
     nullptr); 
if (!status.ok()) { 
    throw runtime_error("Error loading checkpoint from " + checkpointPath + ": " + status.ToString()); 
} 

// and run the inference to your liking 
auto feedDict = ... 
auto outputOps = ... 
std::vector<tensorflow::Tensor> outputTensors; 
status = session->Run(feedDict, outputOps, {}, &outputTensors); 

Для полноты, вот эквивалент Python:

Умозаключение в Python

with tf.Session() as sess: 
    saver = tf.train.import_meta_graph('models/my-model.meta') 
    saver.restore(sess, tf.train.latest_checkpoint('models/')) 
    outputTensors = sess.run(outputOps, feed_dict=feedDict)