[PYTHON] Implémenter Keras LSTM feed forward avec numpy

introduction

Le but de cet article est d'extraire des pondérations du modèle LSTM appris dans Keras et d'implémenter la partie feedforward dans numpy. Pour mon objectif personnel, je voulais jouer avec Keras.

environnement

Créer des données

Pour les données, j'ai utilisé les données de prédiction d'onde sinusoïdale utilisant RNN dans la bibliothèque d'apprentissage en profondeur Keras telles quelles. Cet article semble être basé sur j'ai essayé de prédire en laissant RNN apprendre les ondes de péché, donc je leur suis reconnaissant à tous les deux.

import pandas as pd
import math
import numpy as np

np.random.seed(0)
#Coefficient aléatoire
random_factor = 0.05
#Nombre d'étapes par cycle
steps_per_cycle = 80
#Nombre de cycles à générer
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) 

Créer un modèle

Comme vous pouvez le voir dans la documentation Keras, reportez-vous à ici pour le moment. Cela semble bon. Le modèle sans $ V_o $ dans la partie Notre modèle ci-dessous a été implémenté dans Keras.

Alors, faisons un modèle comme suit, puis faisons une prédiction.

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)

Obtenir les paramètres appris

Obtenez les paramètres du modèle que vous avez appris plus tôt. Cela semble possible avec la méthode get_weights () ''. Cette méthode a été trouvée à la fois dans l'objet keras.models.Sequential '' et dans l'objet keras.layers '', donc avec model.get_weights () '' comme suit: Vous pouvez l'obtenir, ou vous pouvez l'obtenir avec model.layers [0] .get_weights () ``.

model.get_weights()Quel paramètre est quel? Donc, pour le moment, modèle.Après avoir vérifié les couches, etc., modélisez.get_weights()Je pense qu'il vaut mieux l'obtenir avec.




```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)

En regardant le code original, vous pouvez voir cette entrée, oubliez, cellule de mémoire, dans un tableau. Puisque les poids sont stockés dans l'ordre de sortie, ils sont découpés comme ci-dessus.

mon feed forward

La partie formule du document original ne décrivait pas le nombre de dimensions de la matrice, et c'était un peu difficile à lire, alors j'ai soigneusement commenté ce côté. (J'ai l'impression que le code est devenu assez difficile à lire)

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}Veux dire.
Ct_1 = np.zeros(n*h_num).reshape(n,h_num) ##C_{t-1}Veux dire.

ht_list = []

for t in np.arange(x.shape[1]):
    xt = np.array(x[:,t,:])

	#it :porte d'entrée t-term
    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 :Candidat pour la t-ième période de la cellule mémoire
    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 :porte oublier le terme t
    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,)

	#cellule de mémoire t-term
    Ct = it * Ct_tilda + ft * Ct_1

	# ot :porte de sortie t-term
    ot = sigmoid( np.dot(xt, Wo) + np.dot(ht_1, Uo) + bo)
    
    # ht :La couche cachée de la période t
    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

En regardant la documentation Keras, je ne pouvais pas tout à fait comprendre la différence entre les arguments activation et recurrent_activation, mais en regardant le code à l'intérieur, l'activité liée à la cellule mémoire (Ct, Ct_tilde) La fonction d'activation était activation, et la fonction d'activation pour chaque porte (it, ft, ot) était `` `` recurrent_activation. En d'autres termes, dans mon feed-back, la partie qui utilise tanh est activation, et la partie qui utilise sigmoïde est recurrent_activation```.

Graphique des résultats

Comparaison de Keras y_hat et my_y_hat

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 ")

predict1.png

N'est-ce pas un bon sentiment?

Comparaison de ht à chaque t

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")

predict2.png

À mesure que t augmente, le bleu clair devient violet. Vous pouvez voir que lorsque t augmente, il s'approche de la valeur réelle.

À la fin

Je voudrais essayer même les signaux non stationnaires. Keras est facile à lire car le code d'origine est également en python. De plus, la lecture du code original est une expérience très enrichissante.

Recommended Posts

Implémenter Keras LSTM feed forward avec numpy
LSTM multivarié avec Keras
Implémenter LSTM AutoEncoder avec Keras
Débutant RNN (LSTM) | Essayer avec Keras
Implémenter FReLU avec tf.keras
Reconnaissance d'image avec keras
Moyenne mobile avec numpy
Tutoriel CIFAR-10 avec Keras
Premiers pas avec Numpy
Apprenez avec Chemo Informatics NumPy
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
Concaténation de matrices avec Numpy
Code de bourdonnement avec numpy
Effectuer une analyse de régression avec NumPy
Étendre NumPy avec Rust
Régression du noyau avec Numpy uniquement
J'ai écrit GP avec numpy
Implémenter la fonction de connexion avec django-allauth
Implémentation CNN avec juste numpy
Génération artificielle de données avec numpy
Installation de Keras (utilisée par Anaconda)
Implémenter des sous-commandes avec l'argparse de Python
Analyse de régression multiple avec Keras
[Python] Méthode de calcul avec numpy
Essayez l'opération matricielle avec NumPy
Notes AutoEncodder avec Keras
Implémentation de word2vec avec Theano + Keras
Animation de l'équation de diffusion avec NumPy
Implémentation de SMO avec Python + NumPy
Génération de phrases avec GRU (keras)
Coller les chaînes avec Numpy
Implémenter le GPU PyTorch + avec Docker
Créez facilement des CNN avec Keras
[Qt Designer] Implémenter WebView avec PyQt5
Gérez les tableaux numpy avec f2py
Utilisez OpenBLAS avec numpy, scipy
Implémentation d'un GAN efficace avec keras
Implémentez la blockchain avec environ 60 lignes
Reconnaissance d'image avec Keras + OpenCV
Implémentation de la régression logistique avec NumPy