2017-10-01 12 views
1

Ich benutze keras mit dem Tensorflow-Backend.Hidden-State-Vektoren eines LSTM-Modells zu jedem Zeitschritt extrahieren

Ich habe ein geschultes LSTM-Modell, dessen versteckter Zustandsvektor ich bei jedem Zeitschrittextrahieren möchte.

Was ist der beste Weg, dies in Keras zu tun?

+0

Was sind die Parameter für den LSTM-Layer und welche Keras-Version verwenden Sie? Möchten Sie auch den Zellenspeicher (in LSTM-Literaturen normalerweise als "c" bezeichnet) oder nur den versteckten Statusvektor (normalerweise als "h" bezeichnet, der auch die Ausgabe der Ebene darstellt)? Letzteres wäre viel einfacher. –

+0

Ich habe drei gestapelte Bidirektionale LSTMs und ich möchte die versteckten Zustandsvektoren nur der obersten Ebene (ich brauche den Zellenstatus nicht). Ich benutze Keras 2.0.6 – Kiran

Antwort

1

Die Funktion, die behandelt, ob alle versteckten Zustandsvektoren zurückgegeben werden, ist Recurrent.call() (in der neuesten Version wurde sie in RNN.call() umbenannt). Es überprüft den Parameter return_sequences, um die Entscheidung zu treffen.

Wenn die Back-End-Funktion K.rnn() in dieser Funktion aufgerufen wird:

last_output, outputs, states = K.rnn(self.step, 
            preprocessed_input, 
            initial_state, 
            go_backwards=self.go_backwards, 
            mask=mask, 
            constants=constants, 
            unroll=self.unroll, 
            input_length=input_shape[1]) 

... 

if self.return_sequences: 
    output = outputs 
else: 
    output = last_output 

Der Tensor outputs ist das, was Sie wollen. Sie können diesen Tensor erhalten, indem Sie erneut Recurrent.call() aufrufen, aber mit return_sequences=True. Dies sollte Ihrem trainierten LSTM-Modell keinen Schaden zufügen (zumindest in aktuellen Keras).


Hier ist ein Spielzeug Bi-LSTM Modell dieser Methode demonstriert:

input_tensor = Input(shape=(None,), dtype='int32') 
embedding = Embedding(10, 100, mask_zero=True)(input_tensor) 
hidden = Bidirectional(LSTM(10, return_sequences=True))(embedding) 
hidden = Bidirectional(LSTM(10, return_sequences=True))(hidden) 
hidden = Bidirectional(LSTM(2))(hidden) 
out = Dense(1, activation='sigmoid')(hidden) 
model = Model(input_tensor, out) 

Zuerst return_sequences-True für die letzte LSTM Schicht gesetzt (da Sie eine Bidirectional Wrapper verwenden, müssen Sie setzen forward_layer und backward_layer auch):

target_layer = model.layers[-2] 
target_layer.return_sequences = True 
target_layer.forward_layer.return_sequences = True 
target_layer.backward_layer.return_sequences = True 

nun durch diese Schicht wieder aufrufen, die Tensor contai Das Verfolgen versteckter Vektoren zu allen Zeitschritten wird zurückgegeben (es gibt einen Nebeneffekt beim Erstellen eines zusätzlichen eingehenden Knotens, aber dies sollte die Vorhersage nicht beeinflussen).

outputs = target_layer(target_layer.input) 
m = Model(model.input, outputs) 

Sie können durch die versteckten Vektoren erhalten, zum Beispiel m.predict(X_test) aufrufen.

X_test = np.array([[1, 3, 2, 0, 0]]) 
print(m.predict(X_test)) 

[[[ 0.00113332 -0.0006666 0.00428438 -0.00125567] 
    [ 0.00106074 -0.00041183 0.00383953 -0.00027285] 
    [ 0.00080892 0.00027685 0.00238486 0.00036328] 
    [ 0.00080892 0.00027685 0.   0.  ] 
    [ 0.00080892 0.00027685 0.   0.  ]]] 

Wie Sie, versteckte Vektoren aller fünf Zeitschritte sehen können zurückgegeben werden, und die letzten zwei Zeitschritte richtig maskiert sind.

+0

Edited zu verwenden, 'previous()', die leichter zu verstehen sein sollte als mit 'K.function'. –

Verwandte Themen