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, пожалуйста, объясните, если я что-то неправильно понял. Я только недавно начал погружение в код тензорного потока.