[PYTHON] Ich untersuchte die Beziehung zwischen Keras 'zustandsbehaftetem LSTM und verstecktem Zustand

Ich habe Keras 'Stateful LSTM (RNN) Hidden State erneut besucht. Bitte beachten Sie, dass es nicht korrekt ist, da es Informationen im Internet sammelt und auf seine eigene Weise implementiert.

Lesen Sie auch den Artikel, den ich zuvor über den Unterschied zwischen zustandslosem LSTM und zustandsbehaftetem LSTM geschrieben habe. ・ Unterschied zwischen zustandslosem LSTM und zustandsbehaftetem LSTM von Keras

Überblick

Der ursprüngliche Zweck ist [R2D2](https://qiita.com/pocokhc/items/3b64d747a2f36da559c3#%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83 % AC% E3% 82% B9lstm) Implementierung von Burn-In, das wie ein Versuch-und-Irrtum-Weg dahin ist. Ich möchte hidden_states speichern und wiederherstellen, daher habe ich die Änderungen in hidden_states überprüft, als ich model.predict ausgeführt habe.

Verschiedene Informationen

Datensatz

Der Datensatz ist nicht wichtig. Verwenden Sie daher den folgenden Datensatz unverändert. Referenz: Keras: Ex-Tutorials: Stateful LSTM Recurrent Neural Net verstehen

Das Bild ist wie folgt. g1.PNG

Parameter

Anzahl der zu verwendenden Daten: 24 batch_size : 6

Model

Das diesmal verwendete Modell ist wie folgt.

model


c = input_ = Input(batch_shape=(batch_size,) + shape)  #(batch_size,data)
c = LSTM(lstm_units, stateful=True, name="lstm")(c)
c = Dense(y_data.shape[1], activation="softmax")(c)
model = Model(input_, c)

Wir haben die LSTM-Ebene "lstm" genannt, um das spätere Abrufen zu erleichtern. Darüber hinaus gelten bei Verwendung von Stateful LSTM die folgenden Einschränkungen.

Referenz: Wie verwende ich Stateful RNN?

Hidden_states abrufen und einstellen

Das Abrufen von hidden_states ist in Keras wahrscheinlich nicht implementiert, daher erhalten wir es direkt.

from keras import backend as K

def get_hidden_states(model):
    lstm = model.get_layer("lstm")
    hidden_states = [K.get_value(lstm.states[0]), K.get_value(lstm.states[1])]
    return hidden_states

def set_hidden_states(model, hidden_states):
    model.get_layer("lstm").reset_states(hidden_states)

hidden_states hat die folgende Datenstruktur. Die Form ist (2, batch_size, lstm_unit number).

g2.PNG

Lernen

Das Lernen selbst hat keine Bedeutung, daher ist es angemessen.

model.fit(x_data, y_data, epochs=2, batch_size=batch_size, verbose=0)

Daten zum Testen

Im Fall von Stateful kann die Chargengröße nicht geändert werden, sodass auch Testdaten für die Chargengröße erforderlich sind. Erhöhen Sie die gleichen Daten (x_data [0]) um die Stapelgröße.

# create test data
x_test = np.asarray([x_data[0] for _ in range(batch_size)])

Ausgabe der Umfrageergebnisse

Das Bild der Vorhersage ist unten.

g3.PNG

Ich möchte wissen, ob sich die Ergebnisse zwischen den Stapeln ändern, wenn ich den hidden_state ändere. Die Ausgabe gibt also nur den 0. Wert (Wahrscheinlichkeit von A) für jede Charge aus.

def print_result(result):
    for i, r in enumerate(result):
        print("{}: {}".format(i, r[0]))

Umfrage

Fall 1: Ausgabe ohne Zurücksetzen von hidden_states

Da es nicht zurückgesetzt wird, werden die beim Lernen verwendeten hidden_states so verwendet, wie sie sind. Da jeder hidden_state nicht verbunden ist, wird vorausgesagt, dass sich alle Ergebnisse im Stapel ändern werden.

test1_hs speichert an dieser Stelle hidden_states. (Weil ich es danach benutzen werde)

print("--- (1) no reset")
test1_hs = get_hidden_states(model)
print_result( model.predict(x_test, batch_size=batch_size) )

result


--- (1) no reset
0: 0.03929901123046875
1: 0.03843347728252411
2: 0.03823704645037651
3: 0.03934086859226227
4: 0.03969535231590271
5: 0.03939886391162872

Wie erwartet sind sie unzusammenhängend.

Fall 2: Zweite Ausgabe ohne Zurücksetzen von hidden_states

Wie Fall1, jedoch ohne erneutes Zurücksetzen. Es sollte sich von Fall1 unterscheiden.

print("--- (2) no reset 2")
print_result( model.predict(x_test, batch_size=batch_size) )

result


--- (2) no reset 2
0: 0.038682691752910614
1: 0.03798734396696091
2: 0.03784516826272011
3: 0.03870406746864319
4: 0.038950104266405106
5: 0.03872624412178993

Fall3: Stellen Sie hidden_states in Fall1 wieder her

Stellen Sie die in Fall1 gespeicherten hidden_states wieder her. Es sollte der gleiche Wert wie in Fall1 sein.

print("--- (3) restore hidden_state(1)")
set_hidden_states(model, test1_hs)
print_result( model.predict(x_test, batch_size=batch_size) )

result


--- (3) restore hidden_state(1)
0: 0.03929901123046875
1: 0.03843347728252411
2: 0.03823704645037651
3: 0.03934086859226227
4: 0.03969535231590271
5: 0.03939886391162872

Fall 4: Setzen Sie hidden_states zurück

Initialisiere hidden_states mit 0. Sie sollten alle den gleichen Wert haben.

print("--- (4) reset_states")
model.reset_states()
print_result( model.predict(x_test, batch_size=batch_size) )

result


--- (4) reset_states
0: 0.03676648437976837
1: 0.03676648437976837
2: 0.03676648437976837
3: 0.03676648437976837
4: 0.03676648437976837
5: 0.03676648437976837

Fall5: Initialisiert mit hidden_states im 0. Stapel von Fall1

Initialisieren Sie mit hidden_states im 0. Stapel von Case1. Sie sollten den gleichen Wert wie den 0. in Fall1 erhalten.

hidden_states konvertiert ein bisschen gewaltsam ...

# case5
# hidden_Zustände(1)Versteckt_Zustände[0]Vereinige dich mit.
print("--- (5) all same hidden_states")
states0 = []
states1 = []
for i in range(len(test1_hs[0])):
    states0.append(test1_hs[0][0])
    states1.append(test1_hs[1][0])
hidden_states = [np.asarray(states0),np.asarray(states1)]
set_hidden_states(model, hidden_states)
print_result( model.predict(x_test, batch_size=batch_size) )

result


--- (5) all same hidden_states
0: 0.03929901123046875
1: 0.03929901123046875
2: 0.03929901123046875
3: 0.03929901123046875
4: 0.03929901123046875
5: 0.03929901123046875

Zusammenfassung

Das Ergebnis war wie erwartet. Ich frage mich, ob Stateful LSTM jetzt eine Stapelverarbeitung durchführen kann ...

Ganzer Code

from keras.models import Model
from keras.layers import *
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.utils import np_utils
import keras

from keras import backend as K

import numpy as np
import random
import os
import tensorflow as tf

# copy from https://qiita.com/okotaku/items/8d682a11d8f2370684c9
def seed_everything(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    tf.random.set_seed(seed)
    session_conf = tf.compat.v1.ConfigProto(
        intra_op_parallelism_threads=1,
        inter_op_parallelism_threads=1
    )
    sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf)
    tf.compat.v1.keras.backend.set_session(sess)
seed_everything(42)


# define
seq_length = 3
batch_size = 6
lstm_units = 16
shape=(3,1)

# reference: http://torch.classcat.com/2018/06/26/keras-ex-tutorials-stateful-lstm/
#Definieren Sie den Rohdatensatz
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZA"
alphabet_int = [ i for i in range(len(alphabet))]

#Anzahl der Buchstaben(0-25)Erstellen Sie eine Zuordnung zu und umgekehrt.
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))

def int_to_char_seq(seq):
    seq = seq.reshape(seq_length)
    s = ""
    for c in seq:
        c = int(c * float(len(alphabet)))
        s += int_to_char[c]
    return s

# https://keras.io/ja/preprocessing/sequence/
data = TimeseriesGenerator(alphabet_int, alphabet_int, length=seq_length)[0]
x_data = data[0]
y_data = data[1]

# normalize
x_data = x_data / float(len(alphabet))
x_data = np.reshape(x_data, (len(x_data),) + shape )  #(batch_size,len,data)

# one hot encode the output variable
y_data = np_utils.to_categorical(y_data)


# create model
c = input_ = Input(batch_shape=(batch_size,) + shape)  #(batch_size,data)
c = LSTM(lstm_units, stateful=True, name="lstm")(c)
c = Dense(y_data.shape[1], activation="softmax")(c)
model = Model(input_, c)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()

# train
model.fit(x_data, y_data, epochs=2, batch_size=batch_size, verbose=0)



def get_hidden_states(model):
    lstm = model.get_layer("lstm")
    hidden_states = [K.get_value(lstm.states[0]), K.get_value(lstm.states[1])]
    return hidden_states

def set_hidden_states(model, hidden_states):
    model.get_layer("lstm").reset_states(hidden_states)

def print_result(result):
    # result_shape: (batch_size, y_data.shape[1])
    #Da die Menge groß ist, werden nur die 0. Daten als Referenz angezeigt.
    for i, r in enumerate(result):
        print("{}: {}".format(i, r[0]))

# create test data
# x_data[0]Wird um die Chargengröße erhöht
x_test = np.asarray([x_data[0] for _ in range(batch_size)])

# case1
print("--- (1) no reset")
test1_hs = get_hidden_states(model)
print_result( model.predict(x_test, batch_size=batch_size) )

# case2
print("--- (2) no reset 2")
print_result( model.predict(x_test, batch_size=batch_size) )

# case3
print("--- (3) restore hidden_state(1)")
set_hidden_states(model, test1_hs)
print_result( model.predict(x_test, batch_size=batch_size) )

# case4
print("--- (4) reset_states")
model.reset_states()
print_result( model.predict(x_test, batch_size=batch_size) )

# case5
# hidden_Zustände(1)Versteckt_Zustände[0]Vereinige dich mit.
print("--- (5) all same hidden_states")
states0 = []
states1 = []
for i in range(len(test1_hs[0])):
    states0.append(test1_hs[0][0])
    states1.append(test1_hs[1][0])
hidden_states = [np.asarray(states0),np.asarray(states1)]
set_hidden_states(model, hidden_states)
print_result( model.predict(x_test, batch_size=batch_size) )

Recommended Posts

Ich untersuchte die Beziehung zwischen Keras 'zustandsbehaftetem LSTM und verstecktem Zustand
Ich untersuchte das Verhalten bezüglich des Unterschieds zwischen Hard Link und Symbolic Link
Die subtile Beziehung zwischen Gentoo und Pip
Über die Beziehung zwischen Git und GitHub
Untersuchung des Zusammenhangs zwischen Eisausgaben und Temperatur
Ich habe die Datenzuordnung zwischen ArangoDB und Java untersucht
[Statistik] Lassen Sie uns die Beziehung zwischen der Normalverteilung und der Chi-Quadrat-Verteilung visualisieren.
Ich habe versucht, die Unterschiede zwischen Java und Python aufzuzählen
Ich berührte Tensorflow und Keras
Ich habe den Mechanismus der Flaschenanmeldung untersucht!
Ich habe untersucht, wie das Zielfernrohr aussieht
Ich habe die Gerätebaumüberlagerung untersucht
Ich möchte die Verarbeitung zwischen Testzeit und Produktionsumgebung trennen
Ich habe das VGG16-Modell mit Keras implementiert und versucht, CIFAR10 zu identifizieren
Berechnen Sie die Entsprechung zwischen zwei Abteilungen
Schätzen Sie die Verzögerung zwischen zwei Signalen
Die subtile Beziehung zwischen Gentoo und Pip
Über die Beziehung zwischen Git und GitHub
Bayes Modellierung-Schätzung des Unterschieds zwischen den beiden Gruppen-
Untersuchung des Zusammenhangs zwischen Eisausgaben und Temperatur
Untersuchen Sie das doppelte Problem
Berechnen Sie den Zeitunterschied zwischen zwei Spalten mit Pandas DataFrame
Verstehen Sie den Unterschied zwischen der kumulativen Zuordnung zu Variablen und der kumulativen Zuordnung zu Objekten
[Statistik] Lassen Sie uns die Beziehung zwischen der Normalverteilung und der Chi-Quadrat-Verteilung visualisieren.
Ich untersuchte die Beziehung zwischen Keras 'zustandsbehaftetem LSTM und verstecktem Zustand