2016-07-15 23 views
4

Ich würde gerne ein LSTM in Keras laufen und die Ausgabe plus die Zustände erhalten. Manche Dinge wie diese in TFKeras LSTM Zustand

with tf.variable_scope("RNN"): 
     for time_step in range(num_steps): 
     if time_step > 0: tf.get_variable_scope().reuse_variables() 
     (cell_output, state) = cell(inputs[:, time_step, :], state) 
     outputs.append(cell_output) 

Gibt es eine Möglichkeit, dass in Keras zu tun, wo ich den letzten Zustand bekommen und ihn an die neuen Eingänge, wenn die Länge der Sequenz ist riesig. Ich bin mir der Stateful = True bewusst, aber ich möchte Zugang zu den Staaten haben, während ich auch trainiere. Ich weiß, dass es Scan nicht eine for-Schleife verwendet, aber im Grunde möchte ich die Staaten speichern und dann bei meinem nächsten Lauf, sie meine Start-Zustände für die LSTM machen. Kurz gesagt, erhalten Sie sowohl Ausgabe als auch Zustände.

Antwort

2

Da LSTM eine Schicht ist, kann eine Schicht nur eine Ausgabe in Keras (korrigieren Sie mich, wenn ich falsch liege), kann nicht erhalten zwei Ausgabe gleichzeitig ohne Änderung des Quellcodes.

Kürzlich hacken Keras, um einige Vorlaufstruktur zu implementieren, einige Gedanken, die Sie vielleicht nicht mögen, hat funktioniert. Was ich tat, ist überschreiben die Keras Schicht, so dass wir Zugriff auf den Tensor bekommen können, die versteckte Zustände darstellt.

Erstens Ihre call() Funktion in keras/layers/recurrent.py für überprüfen, wie keras tat die Arbeit:

def call(self, x, mask=None): 
    # input shape: (nb_samples, time (padded with zeros), input_dim) 
    # note that the .build() method of subclasses MUST define 
    # self.input_spec with a complete input shape. 
    input_shape = self.input_spec[0].shape 
    if K._BACKEND == 'tensorflow': 
     if not input_shape[1]: 
      raise Exception('When using TensorFlow, you should define ' 
          'explicitly the number of timesteps of ' 
          'your sequences.\n' 
          'If your first layer is an Embedding, ' 
          'make sure to pass it an "input_length" ' 
          'argument. Otherwise, make sure ' 
          'the first layer has ' 
          'an "input_shape" or "batch_input_shape" ' 
          'argument, including the time axis. ' 
          'Found input shape at layer ' + self.name + 
          ': ' + str(input_shape)) 
    if self.stateful: 
     initial_states = self.states 
    else: 
     initial_states = self.get_initial_states(x) 
    constants = self.get_constants(x) 
    preprocessed_input = self.preprocess_input(x) 

    last_output, outputs, states = K.rnn(self.step, preprocessed_input, 
             initial_states, 
             go_backwards=self.go_backwards, 
             mask=mask, 
             constants=constants, 
             unroll=self.unroll, 
             input_length=input_shape[1]) 
    if self.stateful: 
     self.updates = [] 
     for i in range(len(states)): 
      self.updates.append((self.states[i], states[i])) 

    if self.return_sequences: 
     return outputs 
    else: 
     return last_output 

Zweitens sollten wir unsere Ebene außer Kraft setzen, hier ist ein einfaches Skript:

import keras.backend as K 
from keras.layers import Input, LSTM 
class MyLSTM(LSTM): 
    def call(self, x, mask=None): 
    # .... blablabla, right before return 

    # we add this line to get access to states 
    self.extra_output = states 

    if self.return_sequences: 
    # .... blablabla, to the end 

    # you should copy **exactly the same code** from keras.layers.recurrent 

I = Input(shape=(...)) 
lstm = MyLSTM(20) 
output = lstm(I) # by calling, we actually call the `call()` and create `lstm.extra_output` 
extra_output = lstm.extra_output # refer to the target 

calculate_function = K.function(inputs=[I], outputs=extra_output+[output]) # use function to calculate them **simultaneously**. 
+0

By the way , Customizing-Layer verursachen beim Laden und Speichern einen Fehler, da keras 'MyLSTM' beim Laden nicht finden kann. Lassen Sie 'custom_object = {'MyLSTM': MyLSTM}' beim Aufruf von 'model_from_json()'. Es sollte einfach sein. – Van