Der Zweck dieses Artikels besteht darin, Gewichte aus dem in Keras erlernten LSTM-Modell zu extrahieren und den Feedforward-Teil in numpy zu implementieren. Für meinen persönlichen Zweck wollte ich mit Keras spielen.
Für die Daten habe ich die Daten von Sin Wave Prediction unter Verwendung von RNN in der Deep Learning Library Keras verwendet. Dieser Artikel scheint auf Ich habe versucht vorherzusagen, indem ich RNN Sündenwellen lernen ließ zu basieren, daher bin ich beiden dankbar.
import pandas as pd
import math
import numpy as np
np.random.seed(0)
#Zufälliger Koeffizient
random_factor = 0.05
#Anzahl der Schritte pro Zyklus
steps_per_cycle = 80
#Anzahl der zu generierenden Zyklen
number_of_cycles = 50
df = pd.DataFrame(np.arange(steps_per_cycle * number_of_cycles + 1), columns=["t"])
df["sin_t"] = df.t.apply(lambda x: math.sin(x * (2 * math.pi / steps_per_cycle)+ np.random.uniform(-1.0, +1.0) * random_factor))
def _load_data(data, n_prev = 100):
"""
data should be pd.DataFrame()
"""
docX, docY = [], []
for i in range(len(data)-n_prev):
docX.append(data.iloc[i:i+n_prev].as_matrix())
docY.append(data.iloc[i+n_prev].as_matrix())
alsX = np.array(docX)
alsY = np.array(docY)
return alsX, alsY
def train_test_split(df, test_size=0.1, n_prev = 100):
"""
This just splits data to training and testing parts
"""
ntrn = round(len(df) * (1 - test_size))
ntrn = int(ntrn)
X_train, y_train = _load_data(df.iloc[0:ntrn], n_prev)
X_test, y_test = _load_data(df.iloc[ntrn:], n_prev)
return (X_train, y_train), (X_test, y_test)
length_of_sequences = 5
(X_train, y_train), (X_test, y_test) = train_test_split(df[["sin_t"]], n_prev =length_of_sequences)
Wie Sie in Keras-Dokumentation sehen können, lesen Sie vorerst hier. Sieht gut aus. Das Modell ohne $ V_o $ im Abschnitt Unser Modell hier unten wurde in Keras implementiert.
Lassen Sie uns also ein Modell wie folgt erstellen und dann eine Vorhersage treffen.
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import LSTM
in_out_neurons = 1
h_num = 100
model = Sequential()
model.add(LSTM(h_num, activation="tanh", recurrent_activation="sigmoid", batch_input_shape=(None, length_of_sequences, in_out_neurons), return_sequences=False))
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, batch_size=600, epochs=15, validation_split=0.05)
y_hat_keras = model.predict(X_test)
Holen Sie sich die Parameter des Modells, das Sie zuvor gelernt haben. Dies scheint mit der Methode `get_weights ()`
möglich zu sein. Diese Methode wurde sowohl im `keras.models.Sequential```-Objekt als auch im`
keras.layers```-Objekt gefunden, also mit `model.get_weights ()`
wie folgt: Sie können es bekommen, oder Sie können es mit `model.layers [0] .get_weights ()`
bekommen.
model.get_weights()Welcher Parameter ist welcher? Also vorerst Modell.Nach dem Überprüfen von Ebenen usw. Modell.get_weights()Ich denke, es ist besser, es damit zu bekommen.
```python
weights = model.get_weights()
W, U, b, W_out, b_out = model.get_weights()
print("W.shape : ", W.shape)
print("U.shape : ", U.shape)
print("b.shape : ", b.shape)
print("W_out.shape : ", W_out.shape)
print("b_out.shape : ", b_out.shape)
Wi = W[:,0:h_num]
Wf = W[:,h_num:2*h_num]
Wc = W[:,2*h_num:3*h_num]
Wo = W[:,3*h_num:]
print("Wi : ",Wi.shape)
print("Wf : ",Wf.shape)
print("Wc : ",Wc.shape)
print("Wo : ",Wo.shape)
Ui = U[:,0:h_num]
Uf = U[:,h_num:2*h_num]
Uc = U[:,2*h_num:3*h_num]
Uo = U[:,3*h_num:]
print("Ui : ",Ui.shape)
print("Uf : ",Uf.shape)
print("Uc : ",Uc.shape)
print("Uo : ",Uo.shape)
bi = b[0:h_num]
bf = b[h_num:2*h_num]
bc = b[2*h_num:3*h_num]
bo = b[3*h_num:]
print("bi : ",bi.shape)
print("bf : ",bf.shape)
print("bc : ",bc.shape)
print("bo : ",bo.shape)
Wenn Sie sich den Originalcode ansehen, können Sie diese Eingabe, Vergessen, Speicherzelle, in einem Array sehen. Da die Gewichte in der Reihenfolge der Ausgabe gespeichert werden, werden sie wie oben geschnitten.
Der Formelteil des Originaldokuments beschrieb nicht die Anzahl der Dimensionen der Matrix, und es war ein wenig schwierig zu lesen, daher habe ich diese Seite sorgfältig kommentiert. (Ich habe das Gefühl, dass der Code ziemlich schwer zu lesen ist)
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
x = X_test
n = x.shape[0]
#initial
ht_1 = np.zeros(n*h_num).reshape(n,h_num) #h_{t-1}Meint.
Ct_1 = np.zeros(n*h_num).reshape(n,h_num) ##C_{t-1}Meint.
ht_list = []
for t in np.arange(x.shape[1]):
xt = np.array(x[:,t,:])
#it :t-Term-Eingangsgatter
it = sigmoid(np.dot(xt, Wi) + np.dot(ht_1, Ui) + bi)
# it : (390, 100)
# xt : (390, 1), Wi : (1, 100)
# ht_1 : (390, 100), Ui : (100, 100)
# bi : (100,)
# Ct_tilda :Kandidat für die t-te Periode der Speicherzelle
Ct_tilda = np.tanh(np.dot(xt, Wc) + np.dot(ht_1, Uc) + bc)
# Ct_tilda : (390, 100)
# xt : (390, 1), Wc : (1, 100)
# ht_1 : (390, 100), Uc : (100, 100)
# bc : (100,)
# ft :t-term vergessen Tor
ft = sigmoid(np.dot(xt, Wf) + np.dot(ht_1, Uf) + bf)
# ft : (390, 100)
# xt : (390, 1), Wf : (1, 100)
# ht_1 : (390, 100), Uf : (100, 100)
# bf : (100,)
#t-Termgedächtniszelle
Ct = it * Ct_tilda + ft * Ct_1
# ot :t-Term-Ausgangsgatter
ot = sigmoid( np.dot(xt, Wo) + np.dot(ht_1, Uo) + bo)
# ht :versteckte Schicht in der t-Periode
ht = ot * np.tanh(Ct)
ht_list.append(ht)
ht_1 = ht
Ct_1 = Ct
my_y_hat = np.dot(ht, W_out) + b_out
Wenn ich mir die Keras-Dokumentation anschaue, kann ich den Unterschied zwischen den Argumenten "Aktivierung" und "wiederkehrende Aktivierung" nicht ganz verstehen, aber wenn ich mir den Code im Inneren ansehe, die Aktivität in Bezug auf die Speicherzelle (Ct, Ct_tilde) Die Aktivierungsfunktion war "Aktivierung" und die Aktivierungsfunktion für jedes Gate (it, ft, ot) war "wiederkehrende Aktivierung". Mit anderen Worten, in meinem Feed Forward ist der Teil, der Tanh verwendet, "Aktivierung", und der Teil, der Sigmoid verwendet, ist "wiederkehrende Aktivierung".
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(y_test,label="true", color="blue")
ax.plot(y_hat_keras, label="keras y_hat", color="red")
ax.plot(my_y_hat, label="my y_hat", linestyle="dashed", color="green")
ax.legend(loc="upper right")
ax.set_ylabel("y")
ax.set_xlabel("x")
fig.savefig("./predict1.png ")
Ist es nicht ein gutes Gefühl?
import matplotlib.cm as cm
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(y_test, color="red")
for i in np.arange(len(ht_list)):
y_hat_iter = np.dot(ht_list[i], W_out) + b_out
ax.plot(y_hat_iter, color=cm.cool(i/len(ht_list)))
ax.set_ylabel("y")
ax.set_xlabel("x")
fig.savefig("./predict2.png ")
plt.close("all")
Wenn t zunimmt, wird das Hellblau lila. Sie können sehen, dass sich t mit zunehmendem t dem wahren Wert nähert.
Ich möchte auch instationäre Signale ausprobieren. Keras ist leicht zu lesen, da der ursprüngliche Code auch Python ist. Darüber hinaus ist das Lesen des Originalcodes eine ziemliche Lernerfahrung.
Recommended Posts