2017-05-30 4 views
1

Ich bin meine eigene wiederkehrende Schicht in Keras implementieren, und innerhalb der step Funktion möchte ich Zugriff auf die versteckten Zustände über alle Zeitschritte haben, nicht nur den letzten Zustand wie standardmäßig, so dass ich Dinge wie das Hinzufügen von Skip-Verbindungen in der Zeit rückwärts tun könnte.Zurückgeben aller Zustände über Zeitschritte in RNN in Keras

Ich versuche innerhalb K.rnn im Tensorflow Backend zu modifizieren, um alle versteckten Zustände bis jetzt zurückzugeben. Mein erster Gedanke war, jeden versteckten Zustand einfach in einem TensorArray zu speichern und dann all diese an die step_function (d. H. Die step Funktion in meiner Schicht) weiterzuleiten. Meine aktuelle modifizierte Funktion ist die folgende, die jeden verborgenen Zustand in einen TensorArray schreibt states_ta_t:

def _step(time, output_ta_t, states_ta_t, *states): 
      current_input = input_ta.read(time) 
      # Here I'd like to return all states up to current time 
      # and pass to step_function, instead of just the last 
      states = [states_ta_t.read(time)] 
      output, new_states = step_function(current_input, 
               tuple(states) + 
               tuple(constants)) 
      for state, new_state in zip(states, new_states): 
       new_state.set_shape(state.get_shape()) 
      states_ta_t = states_ta_t.write(time+1, new_states[0]) # record states 
      output_ta_t = output_ta_t.write(time, output) 
      return (time + 1, output_ta_t, states_ta_t) + tuple(new_states) 

Diese Version nur den letzten Zustand zurückkehrt, genauso wie die ursprüngliche Implementierung und arbeitet als normaler RNN. Wie kann ich alle bisher im Array gespeicherten Zustände übernehmen und an die step_function übergeben? Es fühlt sich an, als ob dies unglaublich einfach sein sollte, aber ich bin nicht sehr versiert mit TensorArrays ...

(Hinweis: Dies ist einfacher in der abgerollten Version als die symbolische zu tun, aber leider würde ich ausgehen Speicher die abgerollt Version für meine Experimente)

Antwort

2

mit - Herausgegeben -

ich finde, dass ich Ihre Frage falsch verstanden habe, bin ich schrecklich leid, dass ...

kurz gesagt, versuchen Sie dies:

states = states_ta_t.stack()[:time] 

Hier ist eine Erklärung: Sie haben tatsächlich alle diese Zustände in states_ta_t gespeichert, aber Sie haben nur die letzte an Ihre step_function übergeben.

Was Sie in Ihrem Code getan haben, ist:

# Param 'time' refers to 'current time step' 
states = [states_ta_t.read(time)] 

Was bedeutet, dass Sie den ‚aktuellen‘ Zustand von states_ta_t, in anderen Worten lesen, den letzten Zustand.

Wenn Sie stattdessen etwas schneiden möchten, hilft vielleicht die Funktion stack. Zum Beispiel:

states = states_ta_t.stack()[:time] 

Aber ich bin mir nicht sicher, ob dies eine ordnungsgemäße Umsetzung, da ich mit TensorArray entweder nicht vertraut bin ...

Hoffe, es hilft! Wenn nicht, es ist mir eine Ehre, wenn Sie bereit sind, Kommentare zu hinterlassen und mit mir zu diskutieren!

+1

Willkommen bei SO. Bitte lesen Sie diese [how-to-antwort] (http://stackoverflow.com/help/how-to-answer) für eine qualitativ hochwertige Antwort. – thewaywewere

+1

Danke für deinen Rat! Ich werde es lesen und versuchen, meine Antworten zu verbessern :) – Carefree0910

+1

Vielen Dank @ Carefree0910. Das beantwortet meine Frage, ich wusste nicht, dass ich sie auf diese Weise zerlegen könnte :-) Ich habe am Ende realisiert, dass ich auf diese Weise zu viel Speicher verwenden könnte, indem ich alle Zustände gleichzeitig in states_ta_t belasse. Ich habe also zwei TensorArrays erstellt, einen für den aktuellen Zeitschritt und einen für den vorherigen Zeitschritt, mit "clear_after_read = True", so dass ich nur zu einem zusätzlichen Zustand zurückkomme, aber nur zwei Zustände behalten im Speicher zu jeder Zeit. – jodles

Verwandte Themen