TensorFlow freeze_graph.py: имя "save/Const: 0" относится к тензору, который не существует

В настоящее время я пытаюсь экспортировать обучаемую модель TensorFlow в качестве файла ProtoBuf, чтобы использовать ее с API TensorFlow С++ на Android. Поэтому я использую freeze_graph.py script.

Я экспортировал свою модель с помощью tf.train.write_graph:

tf.train.write_graph(graph_def, FLAGS.save_path, out_name, as_text=True)

и я использую контрольную точку, сохраненную с помощью tf.train.Saver.

Я вызываю freeze_graph.py, как описано в верхней части script. После компиляции я запускаю

bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=<path_to_protobuf_file> \
--input_checkpoint=<model_name>.ckpt-10000 \
--output_graph=<output_protobuf_file_path> \
--output_node_names=dropout/mul_1

Это дает мне следующее сообщение об ошибке:

TypeError: Cannot interpret feed_dict key as Tensor: The name 'save/Const:0' refers to a Tensor which does not exist. The operation, 'save/Const', does not exist in the graph.

Как и в случае ошибок, у меня нет тензора save/Const:0 в моей экспортируемой модели. Однако код freeze_graph.py говорит, что это имя тензора можно указать флагом filename_tensor_name. К сожалению, я не могу найти никакой информации о том, каким должен быть этот тензор и как правильно установить его для моей модели.

Может кто-нибудь сказать мне, как создать тензор save/Const:0 в моей экспортированной модели ProtoBuf или как правильно установить флаг filename_tensor_name?

Ответ 1

Флаг --filename_tensor_name используется для указания имени тензора заполнителя, созданного при создании tf.train.Saver для вашей модели. *

В исходной программе вы можете распечатать значение saver.saver_def.filename_tensor_name, чтобы получить значение, которое вы должны передать для этого флага. Вы также можете напечатать значение saver.saver_def.restore_op_name, чтобы получить значение для флага --restore_op_name (поскольку я подозреваю, что значение по умолчанию будет неверным для вашего графика).

В качестве альтернативы, буфер tf.train.SaverDef содержит всю информацию, необходимую для восстановления соответствующей информации для этих флагов. Если вы предпочитаете, вы можете записать saver.saver_def в файл и передать имя этого файла в качестве флага --input_saver на freeze_graph.py.


  * Область имен по умолчанию для tf.train.Saver - "save/", а placeholder - фактически tf.constant(), имя которой по умолчанию на "Const:0", что объясняет, почему флаг по умолчанию равен "save/Const:0".

Ответ 2

Я заметил, что ошибка произошла со мной, когда у меня был код, подобный этому:

sess = tf.Session()
tf.train.write_graph(sess.graph_def, '', '/tmp/train.pbtxt')
init = tf.initialize_all_variables()
saver = tf.train.Saver()
sess.run(init)

Он работал после того, как я изменил макет кода следующим образом:

# Add ops to save and restore all the variables.
saver = tf.train.Saver()    
init = tf.initialize_all_variables()
sess = tf.Session()
tf.train.write_graph(sess.graph_def, '', '/tmp/train.pbtxt')
sess.run(init)

Я не уверен, почему. @mrry вы могли бы объяснить это немного больше?

Ответ 3

Некоторые ответы на вопрос @Drag0 и почему новая раскладка кода исправила ошибку.

При вызове saver = tf.train.Saver() вы добавляете различные переменные, связанные с tf.train.Saver(), такие как 'save/Const:0', в график по умолчанию.

При первом расположении кода график сохраняется до этого без переменных tf.train.Saver(). Во втором расположении кода он сохраняется после, поэтому операция save/Const будет существовать на графике.

Ответ 4

Это не должно быть проблематично в последнем файле freeze_graph.py, поскольку я мог видеть, что они удалены:

del restore_op_name, filename_tensor_name # Unused by updated loading code. источник: freeze_graph.py

В более ранней версии он использовал restore_op для восстановления модели

sess.run([restore_op_name], {filename_tensor_name: input_checkpoint})

Итак, для предыдущей версии, если вы пишете график в файле .pb до создания экземпляра saver op, это будет проблематично. например:.

tf.train.write_graph(sess.graph_def, "./logs", "test2.pb", False)
saver = tf.train.Saver()
saver.save(sess, "./logs/hello_ck.ckpt", meta_graph_suffix='meta', write_meta_graph=True)

Это потому, что для восстановления модели не будет никакого сохранения/восстановления op. Чтобы решить эту проблему, напишите график после сохранения файла .ckpt

saver = tf.train.Saver()
saver.save(sess, "./logs/hello_ck.ckpt", meta_graph_suffix='meta', write_meta_graph=True)
tf.train.write_graph(sess.graph_def, "./logs", "test2.pb", False)

@mrry, пожалуйста, объясните, если я что-то неправильно понял. Я только недавно начал погружение в код тензорного потока.