2017-07-20 2 views
3

Ich möchte den endgültigen Zustand meines LSTM speichern, so dass es bei der Wiederherstellung des Modells enthalten ist und für die Vorhersage verwendet werden kann. Wie unten erläutert, hat der Saver nur Kenntnis über den Endzustand, wenn ich tf.assign verwende. Dies wirft jedoch einen Fehler auf (auch unten erläutert).Tensorflow speichern endgültigen Zustand von LSTM in dynamic_rnn für die Vorhersage

Während des Trainings füttere ich immer den endgültigen LSTM-Status zurück in das Netzwerk, wie in this post erläutert. Hier sind die wichtige Teile des Codes:

Wenn die Grafik Gebäude:

  self.init_state = tf.placeholder(tf.float32, [ 
       self.n_layers, 2, self.batch_size, self.n_hidden 
      ]) 

      state_per_layer_list = tf.unstack(self.init_state, axis=0) 

      rnn_tuple_state = tuple([ 
       tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0], 
               state_per_layer_list[idx][1]) 

       for idx in range(self.n_layers) 
      ]) 

      outputs, self.final_state = tf.nn.dynamic_rnn(
       cell, inputs=self.inputs, initial_state=rnn_tuple_state) 

Und während des Trainings:

 _current_state = np.zeros((self.n_layers, 2, self.batch_size, 
            self.n_hidden)) 

      _train_step, _current_state, _loss, _acc, summary = self.sess.run(
       [ 
        self.train_step, self.final_state, 
        self.merged 
       ], 
       feed_dict={self.inputs: _inputs, 
          self.labels:_labels, 
          self.init_state: _current_state}) 

Als ich später mein Modell von einem Kontrollpunkt wieder herzustellen, der Endzustand ist nicht wieder hergestellt. Wie in this post beschrieben, besteht das Problem darin, dass der Saver den neuen Zustand nicht kennt. Der Beitrag schlägt auch eine Lösung vor, basierend auf tf.assign. Leider kann ich nicht verwenden, um die vorgeschlagene

  assign_op = tf.assign(self.init_state, _current_state) 
      self.sess.run(assign_op) 

weil self.init Zustand keine Variable ist, sondern ein Platzhalter. Ich erhalte die Fehler

Attribute: ‚Tensor‘ Objekt hat kein Attribut ‚zuweisen‘

ich versucht habe, für mehrere Stunden nun, dieses Problem zu lösen, aber ich kann es nicht zu arbeiten.

Jede Hilfe wird geschätzt!

EDIT:

Ich habe mich verändert self.init_state zu

  self.init_state = tf.get_variable('saved_state', shape= 
      [self.n_layers, 2, self.batch_size, self.n_hidden]) 

      state_per_layer_list = tf.unstack(self.init_state, axis=0) 

      rnn_tuple_state = tuple([ 
       tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0], 
               state_per_layer_list[idx][1]) 

       for idx in range(self.n_layers) 
      ]) 

      outputs, self.final_state = tf.nn.dynamic_rnn(
       cell, inputs=self.inputs, initial_state=rnn_tuple_state) 

Und während des Trainings ich keinen Wert für self.init_state füttern:

  _train_step, _current_state, _loss, _acc, summary = self.sess.run(
       [ 
        self.train_step, self.final_state, 
        self.merged 
       ], 
       feed_dict={self.inputs: _inputs, 
          self.labels:_labels}) 

jedoch Ich kann den Auftrag noch immer nicht ausführen. Ich bekomme

Typeerror wissen: Erwartete float32 'Assign' übergeben für den Parameter 'Wert' von op, bekam (LSTMStateTuple (c = array ([[0,07291573, -,06366599, -,23425588, ..., 0,05307654,

+0

Ihre Frage _really_ sieht aus wie ein Duplikat der Verknüpfung. Die akzeptierte Antwort schlägt Ihnen tatsächlich vor, den Platzhalter in eine tf.Variable umzuwandeln, damit Sie den Status im Netzwerk mit TensorFlow-Zuweisungsoperationen aktualisieren können. –

+0

Ja, ich habe es versucht. Vielleicht mache ich einen Fehler, wenn ich es umwandele. Wie wandle ich es richtig in eine tf.Variable um? Die Verwendung von self.init_state = tf.Variable (self.init_state) löst einen Fehler bei der Initialisierung aller Variablen aus. – Lemon

+0

Ich habe die ursprüngliche Frage geändert (siehe Bearbeiten). Es funktioniert immer noch nicht so, wie es in dem anderen Beitrag erklärt wurde. Fehle ich etwas? – Lemon

Antwort

1

Um den endgültigen Status zu speichern, können Sie eine separate TF-Variable erstellen und dann vor dem Speichern des Diagramms eine assign op ausführen, um der Variablen den letzten Status zuzuweisen und das Diagramm zu speichern. Das einzige, was Sie behalten müssen Es ist wichtig, diese Variable zu deklarieren, bevor Sie die Saver deklarieren, andernfalls wird sie nicht in das Diagramm aufgenommen.

Dies wird hier ausführlich besprochen, einschließlich des Arbeitscodes: TF LSTM: Save State from training session for prediction session later

*** UPDATE: Antworten auf Fragen followup:

Es sieht aus wie Sie BasicLSTMCell verwenden, mit state_is_tuple=True. Die vorherige Diskussion, auf die ich Sie bezog, verwendete GRUCell mit state_is_tuple=False.Die Details zwischen den beiden sind etwas anders, aber der gesamte Ansatz könnte ähnlich sein, also sollte dies hoffentlich für Sie funktionieren:

Während des Trainings, zuerst füttern Sie Nullen als initial_state in dynamic_rnn und dann weiter Feed seinen eigenen Ausgang zurück als Eingabe als initial_state. Der LAST-Ausgangszustand unseres dynamic_rnn-Aufrufs ist also der, den Sie für später speichern möchten. Da es sich um einen sess.run() Aufruf handelt, handelt es sich im Wesentlichen um ein numpiges Array (kein Tensor und kein Platzhalter). Die Frage lautet also: "Wie speichere ich ein numpiges Array als Tensorflow-Variable zusammen mit den restlichen Variablen im Diagramm?" Aus diesem Grund weisen Sie den Endstatus einer Variablen zu, deren einziger Zweck darin besteht.

So ist Code etwa wie folgt:

# GRAPH DEFINITIONS: 
    state_in = tf.placeholder(tf.float32, [LAYERS, 2, None, CELL_SIZE], name='state_in') 
    l = tf.unstack(state_in, axis=0) 
    state_tup = tuple(
     [tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1]) 
     for idx in range(NLAYERS)]) 
    #multicell = your BasicLSTMCell/MultiRNN definitions 
    output, state_out = tf.nn.dynamic_rnn(multicell, X, dtype=tf.float32, initial_state=state_tup) 

    savedState = tf.get_variable('savedState', shape=[LAYERS, 2, BATCHSIZE, CELL_SIZE]) 
    saver = tf.train.Saver(max_to_keep=1) 

    in_state = np.zeros((LAYERS, 2, BATCHSIZE, CELL_SIZE)) 

    # TRAINING LOOP: 
    feed_dict = {X: x, Y_: y_, batchsize: BATCHSIZE, state_in:in_state} 
    _, out_state = sess.run([training_step, state_out], feed_dict=feed_dict) 
    in_state = out_state 

    # ONCE TRAINING IS OVER: 
    assignOp = tf.assign(savedState, out_state) 
    sess.run(assignOp) 
    saver.save(sess, pathModel + '/my_model.ckpt') 

    # RECOVERING IN A DIFFERENT PROGRAM: 

    gInit = tf.global_variables_initializer().run() 
    lInit = tf.local_variables_initializer().run() 
    new_saver = tf.train.import_meta_graph(pathModel + 'my_model.ckpt.meta') 
    new_saver.restore(sess, pathModel + 'my_model.ckpt') 
    # retrieve State and get its LAST batch (latest obervarions) 
    savedState = sess.run('savedState:0') # this is FULL state from training 
    state = savedState[:,:,-1,:] # -1 gets only the LAST batch of the state (latest seen observations) 
    state = np.reshape(state, [state.shape[0], 2, -1, state.shape[2]]) #[LAYERS, 2, 1 (BATCH), SELL_SIZE] 
    #x = .... (YOUR INPUTS) 
    feed_dict = {'X:0': x, 'state_in:0':state} 
    #PREDICTION LOOP: 
    preds, state = sess.run(['preds:0', 'state_out:0'], feed_dict = feed_dict) 
    # so now state will be re-fed into feed_dict with the next loop iteration 

Wie bereits erwähnt, ist dies ein modifizierter Ansatz von dem, was für mich funktioniert gut mit GRUCell, wo state_is_tuple = False. Ich habe es angepasst, um BasicLSTMCell mit state_is_tuple=True auszuprobieren. Es funktioniert, aber nicht so genau wie der ursprüngliche Ansatz. Ich weiß noch nicht, ob es nur weil für mich GRU besser ist als LSTM oder aus irgendeinem anderen Grund. Sehen Sie, ob das für Sie funktioniert ...

Denken Sie auch daran, dass Ihre Vorhersagen wahrscheinlich auf einer anderen Batchgröße basieren als Ihre Trainingsschleife (ich nehme an, dass Batch von 1?) Also musst du darüber nachdenken, wie du mit deinem wiedererlangten Zustand umgehen musst - nimm nur die letzte Ladung? Oder etwas anderes? Dieser Code nimmt nur die letzte Ebene des gespeicherten Status (d. H. Die neuesten Beobachtungen aus dem Training), da das für mich relevant war ...

+0

Ja. Ich habe diese Diskussion gesehen und den Link in meinem Beitrag bereitgestellt. Der mitgelieferte Code lässt jedoch große Teile weg, deshalb hat es nicht geholfen. Wenn ich Sie richtig verstehe, wird die Variable "savedState" in Ihrem Beitrag nur dazu verwendet, in jeder Epoche den letzten LSTM-Status zuzuweisen? Aber wie ernährst du dich in den LSTM-Staaten während des Trainings? Verwenden Sie einen Platzhalter wie oben beschrieben? In Ihrem Beitrag wird das "Feed-Diktat" nie vollständig spezifiziert. – Lemon

+0

Auch der Code zum Wiederherstellen der Variablen ist nicht klar. Sie starten sess.run ('savedState: 0'), um den letzten lstm-Status im Training zu erhalten. Aber wie füttern Sie diese Informationen ins Netz? Welcher Variable oder Platzhalter ist es gegeben? – Lemon

+0

Apols .. Ihre Frage gefragt, wie Sie den FINAL-Status für die Vorhersage speichern, also nehme ich an, Sie waren in Ordnung mit, wie alles vorher getan wird. Ich werde meine Antwort in wenigen Sekunden aktualisieren .. –

Verwandte Themen