2016-04-23 15 views
1

Ich habe zwei separate Tensorflow-Prozesse, eine, die ein Modell trainiert und graph_defs mit tensorflow.python.client.graph_util.convert_variables_to_constants schreiben, und eine andere, die die graph_def mit tensorflow.import_graph_def liest. Ich möchte, dass der zweite Prozess den graph_def regelmäßig aktualisiert, wenn er vom ersten Prozess aktualisiert wird. Leider scheint es, dass jedes Mal, wenn ich das Diagramm lese, das alte immer noch verwendet wird, selbst wenn ich die aktuelle Sitzung schließe und eine neue erstelle. Ich habe auch versucht, die import_graph_def call mit sess.graph.as_default(), vergeblich zu wickeln. Hier ist mein aktueller graph_def Ladecode:Nachladen Tensorflow-Modell

if self.sess is not None: 
    self.sess.close() 
self.sess = tf.Session() 

graph_def = tf.GraphDef() 
with open(self.graph_path, 'rb') as f: 
    graph_def.ParseFromString(f.read()) 
with self.sess.graph.as_default(): 
    tf.import_graph_def(graph_def, name='') 

Antwort

5

Das Problem hier ist, dass, wenn Sie ein tf.Session ohne Argumente zu erstellen, verwendet es den aktuellen Standarddiagramm. Angenommen, Sie erstellen an keiner anderen Stelle in Ihrem Code eine tf.Graph, erhalten Sie das globale Standarddiagramm, das beim Start des Prozesses erstellt wird und von allen Sitzungen gemeinsam genutzt wird. Als Ergebnis hat with self.sess.graph.as_default(): keinen Effekt.

Es ist schwer, eine neue Struktur aus dem Snippet Sie in der Frage zeigte — insbesondere zu empfehlen, ich habe keine Ahnung, wie man das vorherige Diagramm erstellt, oder das, was die Klassenstruktur ist — aber eine Möglichkeit wäre, zu ersetzen die self.sess = tf.Session() mit dem folgenden:

self.sess = tf.Session(graph=tf.Graph()) # Creates a new graph for the session. 

Nun ist die with self.sess.graph.as_default(): wird die Grafik verwenden, die für die Sitzung, und das Programm sollte die beabsichtigte Wirkung hat erstellt wurde.

Eine etwas vorzuziehen (für mich zumindest) Alternative wäre, den Graphen explizit zu bauen:

with tf.Graph().as_default() as imported_graph: 
    tf.import_graph_def(graph_def, ...) 

sess = tf.Session(graph=imported_graph) 
+0

Da die Graphen Ich verwende alle die gleiche Struktur haben, nur unterschiedliche Gewichte, ich denke, es wäre effizienter sein, das Diagramm einmal zu laden und dann nur die Variablen zu laden, die etwas wie 'Saver.restore()' verwenden. Ich habe das versucht und es scheint, dass nachfolgende Aufrufe von Saver.restore() keine Wirkung haben. Gibt es einen Weg, dies zu erreichen? –

+1

Ja, das klingt, als sollte es funktionieren. Mehrere Aufrufe von 'Saver.restore()' sollten Auswirkungen haben, also bin ich mir nicht sicher, was aber schief läuft. Verwenden Sie einen einzelnen Graphen und eine einzelne "tf.Session"? – mrry

+0

Es scheint, dass ich falsch lag, mehrere Aufrufe von 'restore()' haben Wirkung, und sie sind ziemlich viel schneller als das Laden des gesamten Graphen (so schnell, dass es mich denken ließ, dass sie nichts tun!). Ich denke, ich werde von nun an nur 'restore() 'ausführen, es sei denn, in Zukunft muss ich das Diagramm erneut in C++ ausführen. –