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
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.
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.
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?
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).
Das Lernen selbst hat keine Bedeutung, daher ist es angemessen.
model.fit(x_data, y_data, epochs=2, batch_size=batch_size, verbose=0)
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)])
Das Bild der Vorhersage ist unten.
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]))
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.
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
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
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
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
Das Ergebnis war wie erwartet. Ich frage mich, ob Stateful LSTM jetzt eine Stapelverarbeitung durchführen kann ...
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