Ich kann das Modul optimize_for_inference
nicht erfolgreich in einem einfachen, gespeicherten TensorFlow-Diagramm (Python 2.7; von pip install tensorflow-gpu==1.0.1
installiertes Paket) ausführen.
Hier ist mein Python-Skript zum Generieren und Speichern eines einfachen Graphen, um meiner Eingabe x
placeholder
5 hinzuzufügen.
import tensorflow as tf
# make and save a simple graph
G = tf.Graph()
with G.as_default():
x = tf.placeholder(dtype=tf.float32, shape=(), name="x")
a = tf.Variable(5.0, name="a")
y = tf.add(a, x, name="y")
saver = tf.train.Saver()
with tf.Session(graph=G) as sess:
sess.run(tf.global_variables_initializer())
out = sess.run(fetches=[y], feed_dict={x: 1.0})
print(out)
saver.save(sess=sess, save_path="test_model")
Ich habe ein einfaches Restore-Skript, das das gespeicherte Diagramm neu erstellt und Diagrammparameter wiederherstellt. Beide Save/Restore-Skripte erzeugen die gleiche Ausgabe.
import tensorflow as tf
# Restore simple graph and test model output
G = tf.Graph()
with tf.Session(graph=G) as sess:
# recreate saved graph (structure)
saver = tf.train.import_meta_graph('./test_model.meta')
# restore net params
saver.restore(sess, tf.train.latest_checkpoint('./'))
x = G.get_operation_by_name("x").outputs[0]
y = G.get_operation_by_name("y").outputs
out = sess.run(fetches=[y], feed_dict={x: 1.0})
print(out[0])
Ich erwarte zwar nicht viel Optimierung, aber wenn ich versuche, den Graphen für die Inferenz zu optimieren, erhalte ich die folgende Fehlermeldung. Der erwartete Ausgabeknoten scheint nicht in der gespeicherten Grafik zu sein.
$ python -m tensorflow.python.tools.optimize_for_inference --input test_model.data-00000-of-00001 --output opt_model --input_names=x --output_names=y
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/{path}/lib/python2.7/site-packages/tensorflow/python/tools/optimize_for_inference.py", line 141, in <module>
app.run(main=main, argv=[sys.argv[0]] + unparsed)
File "/{path}/local/lib/python2.7/site-packages/tensorflow/python/platform/app.py", line 44, in run
_sys.exit(main(_sys.argv[:1] + flags_passthrough))
File "/{path}/lib/python2.7/site-packages/tensorflow/python/tools/optimize_for_inference.py", line 90, in main
FLAGS.output_names.split(","), FLAGS.placeholder_type_enum)
File "/{path}/local/lib/python2.7/site-packages/tensorflow/python/tools/optimize_for_inference_lib.py", line 91, in optimize_for_inference
placeholder_type_enum)
File "/{path}/local/lib/python2.7/site-packages/tensorflow/python/tools/strip_unused_lib.py", line 71, in strip_unused
output_node_names)
File "/{path}/local/lib/python2.7/site-packages/tensorflow/python/framework/graph_util_impl.py", line 141, in extract_sub_graph
assert d in name_to_node_map, "%s is not in graph" % d
AssertionError: y is not in graph
Weitere Untersuchungen veranlassten mich, den Kontrollpunkt des gespeicherten Graphen zu untersuchen, der nur einen Tensor (a
, keine x
und keine y
) anzeigt.
(tf-1.0.1) $ python -m tensorflow.python.tools.inspect_checkpoint --file_name ./test_model --all_tensors
tensor_name: a
5.0
x
und y
? Liegt es daran, dass es sich um Operationen handelt und nicht um Tensoren?optimize_for_inference
-Modul angeben muss, damit ich auf die Eingabe- und Ausgabeknoten verweisen kann?Hier ist die detaillierte Anleitung, wie Sie die Inferenz optimieren können:
Das optimize_for_inference
-Modul nimmt eine frozen binary GraphDef
-Datei als Eingabe und gibt die optimized Graph Def
-Datei aus, die Sie für die Inferenz verwenden können. Um den frozen binary GraphDef file
zu erhalten, müssen Sie das Modul freeze_graph
verwenden, das einen GraphDef proto
, einen SaverDef proto
und einen Satz von Variablen benötigt, die in einer Prüfpunktdatei gespeichert sind. Die Schritte, um dies zu erreichen, sind unten angegeben:
# make and save a simple graph
G = tf.Graph()
with G.as_default():
x = tf.placeholder(dtype=tf.float32, shape=(), name="x")
a = tf.Variable(5.0, name="a")
y = tf.add(a, x, name="y")
saver = tf.train.Saver()
with tf.Session(graph=G) as sess:
sess.run(tf.global_variables_initializer())
out = sess.run(fetches=[y], feed_dict={x: 1.0})
# Save GraphDef
tf.train.write_graph(sess.graph_def,'.','graph.pb')
# Save checkpoint
saver.save(sess=sess, save_path="test_model")
python -m tensorflow.python.tools.freeze_graph --input_graph graph.pb --input_checkpoint test_model --output_graph graph_frozen.pb --output_node_names=y
python -m tensorflow.python.tools.optimize_for_inference --input graph_frozen.pb --output graph_optimized.pb --input_names=x --output_names=y
with tf.gfile.GFile('graph_optimized.pb', 'rb') as f:
graph_def_optimized = tf.GraphDef()
graph_def_optimized.ParseFromString(f.read())
G = tf.Graph()
with tf.Session(graph=G) as sess:
y, = tf.import_graph_def(graph_def_optimized, return_elements=['y:0'])
print('Operations in Optimized Graph:')
print([op.name for op in G.get_operations()])
x = G.get_tensor_by_name('import/x:0')
out = sess.run(y, feed_dict={x: 1.0})
print(out)
#Output
#Operations in Optimized Graph:
#['import/x', 'import/a', 'import/y']
#6.0
Wenn mehrere Ausgabeknoten vorhanden sind, geben Sie Folgendes an: output_node_names = 'boxes, scores, classes'
und importieren Sie das Diagramm mit
boxes,scores,classes, = tf.import_graph_def(graph_def_optimized, return_elements=['boxes:0', 'scores:0', 'classes:0'])
input
ist eine graphdef-Datei für das script und nicht der Datenteil des Prüfpunkts. Sie müssen das Modell in eine .pb
-Datei einfrieren/oder den Prototxt für das Diagramm abrufen und das Inferenz-Skript optimieren verwenden. This script takes either a frozen binary GraphDef file (where the weight
variables have been converted into constants by the freeze_graph script), or a
text GraphDef proto file (the weight variables are stored in a separate
checkpoint file), and outputs a new GraphDef with the optimizations applied.