2017-03-17 5 views
6

Ich trainiere gerade ein rekurrentes neuronales Netzwerk für die Wettervorhersage mit einer LSTM-Schicht. Das Netzwerk selbst ist ziemlich einfach und sieht in etwa wie folgt aus:Wie interpretiere ich Gewichte in einer LSTM-Schicht in Keras?

model = Sequential() 
model.add(LSTM(hidden_neurons, input_shape=(time_steps, feature_count), return_sequences=False)) 
model.add(Dense(feature_count)) 
model.add(Activation("linear")) 

Die Gewichte der LSTM Schicht die folgenden Formen zu tun haben:

for weight in model.get_weights(): # weights from Dense layer omitted 
    print(weight.shape) 

> (feature_count, hidden_neurons) 
> (hidden_neurons, hidden_neurons) 
> (hidden_neurons,) 
> (feature_count, hidden_neurons) 
> (hidden_neurons, hidden_neurons) 
> (hidden_neurons,) 
> (feature_count, hidden_neurons) 
> (hidden_neurons, hidden_neurons) 
> (hidden_neurons,) 
> (feature_count, hidden_neurons) 
> (hidden_neurons, hidden_neurons) 
> (hidden_neurons,) 

Kurz gesagt, es sieht aus wie es vier „Elemente“ sind in dieser LSTM-Ebene. Ich frage mich nun, wie sie zu interpretieren:

  • Wo ist der time_steps Parameter in dieser Darstellung? Wie beeinflusst es die Gewichte?

  • Ich habe gelesen, dass ein LSTM besteht aus mehreren Blöcken, wie ein Eingang und ein vergessenes Tor. Wenn diese in diesen Gewichtsmatrizen dargestellt werden, welche Matrix gehört zu welchem ​​Gatter?

  • Gibt es eine Möglichkeit zu sehen, was das Netzwerk gelernt hat? Zum Beispiel, wie viel kostet es vom letzten Zeitschritt (t-1, wenn wir t prognostizieren möchten) und wie viel von t-2 usw.? Es wäre interessant zu wissen, ob wir aus den Gewichten lesen könnten, dass beispielsweise der Eingang t-5 völlig irrelevant ist.

Klarstellungen und Hinweise würden sehr geschätzt werden.

Antwort

1

Ich werde wahrscheinlich nicht alle Ihre Fragen beantworten können, aber was ich tun kann, ist mehr Informationen über die LSTM-Zelle und die verschiedenen Komponenten, aus denen sie besteht.

This post on github schlägt eine Art und Weise die Parameter Namen zu sehen, während sie den Druck:

model = Sequential() 
model.add(LSTM(4,input_dim=5,input_length=N,return_sequences=True)) 
for e in zip(model.layers[0].trainable_weights, model.layers[0].get_weights()): 
    print('Param %s:\n%s' % (e[0],e[1])) 

Ausgabe wie folgt aussieht:

Param lstm_3_W_i: 
[[ 0.00069305, ...]] 
Param lstm_3_U_i: 
[[ 1.10000002, ...]] 
Param lstm_3_b_i: 
[ 0., ...] 
Param lstm_3_W_c: 
[[-1.38370085, ...]] 
... 

Jetzt können Sie here weitere Informationen über diese verschiedenen Gewichte finden. Sie haben Namen W, U, V und b mit verschiedenen Indizes.

  • W-Matrizen sind solche, die die Eingaben in andere interne Werte umwandeln. Sie haben die Form [input_dim, output_dim].
  • U-Matrizen sind solche, die den vorherigen verborgenen Zustand in einen anderen internen Wert umwandeln. Sie haben die Form [output_dim, output_dim].
  • b Vektoren sind die Vorspannung für jeden Block. Sie alle haben die Form [output_dim]
  • V wird nur im Ausgangstor verwendet, es wählt aus, welche Werte aus dem neuen internen Zustand ausgegeben werden sollen. Es hat eine Form [output_dim, output_dim]

Kurz gesagt haben Sie tatsächlich 4 verschiedene "Blöcke" (oder interne Schichten).

  • Gate vergessen: Er entscheidet, basierend auf dem vorherigen verborgenen Zustand (H_ {t-1}) und den Eingang (x), die aus dem vorherigen internen Zustand der Zelle vergessen Werten (C_ {t -1}):

    F_T = sigmoid (W_f * x + U_F * H_ {t-1} + b_f)

    F_T ist ein Vektor, der Werte zwischen 0 und 1, die codieren, was zu halten (= 1) und was zu vergessen (= 0) vom vorherigen Zellenstatus.

  • Eingangsgatter: Er entscheidet, basierend auf dem vorherigen verborgenen Zustand (H_ {t-1}) und der Eingang (x), die von dem Eingang zu verwendenden Werten (x):

    I_t = sigmoid (W_i * x + U_i * h_ {t-1} + b_i)

    i_t ist ein Vektor mit Werten zwischen 0 und 1, der codiert, welche Werte verwendet werden, um den neuen Zellenstatus zu aktualisieren.

  • Kandidatenwert: Wir bauen neue Kandidatenwerte der internen Zellzustand zu aktualisieren, wobei der Eingang (x) und den vorherigen verborgenen Zustand (h_ {t-1}) mit:

    Ct_t = tanh (W_c * x + U_c * h_ {t-1} + b_c)

    Ct_t ist ein Vektor, der potenzielle Werte enthält, um den Zellenstatus (C_ {t-1}) zu aktualisieren.

Wir verwenden diese drei Werte einen neuen internen Zellzustand (C_T) zu bauen:

C_T = F_T * C_ {t-1} + I_t * Ct_t

wie Sie sehen können, Der neue interne Zellenzustand besteht aus zwei Dingen: dem Teil, den wir vom letzten Zustand nicht vergessen haben, und dem, was wir aus der Eingabe lernen wollten.

  • Output Gate: wir wollen nicht den Zellenzustand ausgeben, wie es als eine Abstraktion von gesehen werden könnte, was wir ausgeben wollen (h_t). So bauen wir h_t, die Ausgabe für diesen Schritt auf der Grundlage aller Informationen, die wir haben:

    h_t = W_o * x + U_o * h_ {t-1} + V_o * C_T + b_o

I hoffe das verdeutlicht, wie eine LSTM-Zelle funktioniert. Ich lade Sie ein, Tutorials zu LSTM zu lesen, da sie nette Schemata, Schritt-für-Schritt-Beispiele und so weiter verwenden. Es ist eine relativ komplexe Schicht.

In Bezug auf Ihre Fragen habe ich jetzt eine Idee, wie Sie verfolgen, was aus den Eingaben verwendet wurde, um den Zustand zu ändern. Sie könnten schließlich die verschiedenen W-Matrizen betrachten, da sie die Eingabe verarbeiten. Der W_c gibt Ihnen Informationen darüber, was möglicherweise zum Aktualisieren des Zellenstatus verwendet wird. W_o könnte Ihnen einige Informationen darüber geben, was zur Erzeugung der Ausgabe verwendet wird ... Aber all dies wird relativ zu den anderen Gewichten sein, da die vorherigen Zustände ebenfalls einen Einfluss haben.

Wenn Sie in W_c jedoch einige starke Gewichte sehen, dann bedeutet das vielleicht nichts, weil das Eingabegatter (i_t) vielleicht komplett geschlossen ist und die Aktualisierung des Zellenzustands aufhört ... Es ist komplex, das Feld von Mathematik, die zurück verfolgt, was in einem Neuronalen Netz passiert, ist wirklich komplex.

Neuronale Netze sind wirklich schwarze Kästchen für den allgemeinsten Fall. Sie können in der Literatur einige Fälle finden, in denen sie Informationen von Ausgang zu Eingang zurückverfolgen, aber das ist in sehr speziellen Fällen von dem, was ich gelesen habe.

Ich hoffe, das hilft :-)

+0

Der obige Code wie von Github veröffentlicht ist wahrscheinlich veraltet und nicht mehr die Informationen W_i geben und so weiter. Da ich einige Werte von diesen Gates benötige, gibt es einen neueren Weg zu finden, welches Gewicht in der Gewichtsmatrix dem entspricht. Ich würde Sie bitten, mir mit einer neueren Version von @NassimBen zu helfen –

Verwandte Themen