[PYTHON] Décodage du modèle LSTM de Keras.

Aperçu

J'ai utilisé Keras et Tensorflow pour calculer les poids de mon réseau de neurones, mais il est étonnamment difficile de savoir comment l'utiliser dans de vraies applications (applications iPhone, applications Android, Javascript, etc.).

S'il s'agit d'un simple réseau de neurones, c'est simple, mais comme il fallait utiliser les poids appris en LSTM cette fois, j'ai déchiffré le contenu de Predict of LSTM de Keras.

Les poids appris peuvent être récupérés avec model.get_weights (), mais aucune information sur celui-ci ne sort même si je la recherche sur Google.

Après tout, suite à l'écriture du code et à son essai au hasard, les poids récupérés par model.get_weights () sont Premier (indice 0): poids de couche d'entrée LSTM pour les entrées, poids de porte d'entrée, poids de porte de sortie, poids de porte d'oubli Deuxième (indice 1): poids d'entrée de la couche cachée, poids de la porte d'entrée, poids de la porte de sortie, poids de la porte d'oubli Troisième (index 2): biais pour la couche d'entrée et la couche cachée Quatrième (indice 3): poids pour l'entrée de couche de sortie (poids pour la sortie de couche cachée) Cinquième (indice 4): biais vers la couche de sortie (biais vers la sortie de la couche cachée) J'ai découvert.

Pour comprendre cela, j'ai écrit le code qui (se comportera) comme model.predict () à la fin.

J'espère que la page officielle de Keras a quelque chose comme ça. .. .. ..

Sortie de get_weigts ()

Si weights = model.get_weights (), les poids suivants sont stockés. image3.png

Le nombre 1951 est le nombre de nœuds dans la couche d'entrée, donc il n'y a pas de problème. L'index 3 128 a également le nombre de nœuds de couche masqués défini sur 128, de sorte qu'il peut être considéré comme un poids pour la sortie de la couche masquée. Le problème était 512, ce qui était le plus déroutant.

J'ai soudainement imaginé que quatre types de «poids pour l'entrée, poids pour les portes d'entrée, poids pour les portes de sortie et poids pour les portes d'oubli» sont stockés. Cependant, en regardant la page officielle de Keras, il y a une déclaration que LSTM utilise (unité de stockage à long et court terme - Hochreiter 1997.). En parlant de 1997, la porte de l'oubli n'était pas pondérée. .. .. ?? Il semble que la porte de l'oubli ait été créée en 1999. .. .. .. C'est ce qu'il dit ici aussi ...? http://kivantium.hateblo.jp/entry/2016/01/31/222050

Bien que cela me dérange, j'ai pensé que si j'écrivais le code en solide, ceux-ci seraient clarifiés, alors j'ai décidé d'écrire ce code qui se comporte de la même manière que model.predict.

Code pour démêler model.predict ()

En guise de prémisse, le modèle de LSTM utilisé pour le décodage cette fois est le suivant. Exemple de code pour générer des phrases à l'aide de LSTM.

from __future__ import print_function
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LSTM
from keras.optimizers import RMSprop
from keras.utils.data_utils import get_file
import numpy as np
import random
import sys
from keras.models import model_from_json
import copy
import matplotlib.pyplot as plt
import math

#path = get_file('nietzsche.txt', origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
text = open('hokkaido_x.txt', 'r', encoding='utf8').read().lower()
print('corpus length:', len(text))

chars = sorted(list(set(text)))
print('total chars:', len(chars))
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))

# cut the text in semi-redundant sequences of maxlen characters
#maxlen = 40
maxlen = 3
step = 2
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
    sentences.append(text[i: i + maxlen])
    next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))

print('Vectorization...')
X = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
    for t, char in enumerate(sentence):
        X[i, t, char_indices[char]] = 1
    y[i, char_indices[next_chars[i]]] = 1


# build the model: a single LSTM
print('Build model...')
model = Sequential()
model.add(LSTM(128, input_shape=(maxlen, len(chars)),activation='sigmoid',inner_activation='sigmoid'))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))

optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)


def sample(preds, temperature=1.0):
    # helper function to sample an index from a probability array
    preds = np.asarray(preds).astype('float64')
    preds = np.log(preds) / temperature
    exp_preds = np.exp(preds)
    preds = exp_preds / np.sum(exp_preds)
    probas = np.random.multinomial(1, preds, 1)
    return np.argmax(probas)
    
    
model.fit(X, y, batch_size=64, epochs=1)

diversity = 0.5
print()

generated = ''
sentence = "Godzilla"
#    sentence = text[start_index: start_index + maxlen]
generated += sentence
  #        print('----- Generating with seed: "' + sentence + '"')
  #  sys.stdout.write(generated)
  
  #        for i in range(400):
x = np.zeros((1, maxlen, len(chars)))
for t, char in enumerate(sentence):
    x[0, t, char_indices[char]] = 1.
  
preds = model.predict(x, verbose=0)[0]

plt.plot(preds,'r-')
plt.show()

D'autre part, le code suivant renvoie la même valeur que «model.predict». Je suis fatigué d'écrire pour des déclarations, donc je les ai décrites comme c1, c2, c3, etc., mais ces nombres correspondent à maxlen dans le modèle ci-dessus. Si vous souhaitez augmenter maxlen, vous pouvez créer une structure de boucle avec un document for. Pour le code, je me suis référé au site suivant. http://blog.yusugomori.com/post/154208605320/javascript%E3%81%AB%E3%82%88%E3%82%8Bdeep-learning%E3%81%AE%E5%AE%9F%E8%A3%85long-short-term

print(preds)

weights = model.get_weights()

 
obj=weights                       
                             
w1=obj[0]
w2=obj[1]
w3=obj[2]
w4=obj[3]
w5=obj[4]

hl = 128

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))

def activate(x):
    x[0:hl] = sigmoid(x[0:hl]) #i
    x[hl:hl*2] = sigmoid(x[hl:hl*2]) #a
    x[hl*2:hl*3] = sigmoid(x[hl*2:hl*3]) #f
    x[hl*3:hl*4] = sigmoid(x[hl*3:hl*4]) #o
    return x
    
def cactivate(c):
    return sigmoid(c)

x1 = np.array(x[0,0,:])
x2 = np.array(x[0,1,:])
x3 = np.array(x[0,2,:])

h1 = np.zeros(hl)
c1 = np.zeros(hl)

o1 = x1.dot(w1)+h1.dot(w2)+w3
o1 = activate(o1)

c1 = o1[0:hl]*o1[hl:hl*2] + o1[hl*2:hl*3]*c1
#c1 = o1[0:128]*o1[128:256] + c1

h2 = o1[hl*3:hl*4]*cactivate(c1)

#2e
o2 =  x2.dot(w1)+h2.dot(w2)+w3
o2 = activate(o2)

c2 = o2[0:hl]*o2[hl:hl*2] + o2[hl*2:hl*3]*c1
#c2 = o2[0:128]*o2[128:256] + c1

h3 = o2[hl*3:hl*4]*cactivate(c2)

#3e
o3 = x3.dot(w1)+h3.dot(w2)+w3
o3 = activate(o3)

c3 = o3[0:hl]*o3[hl:hl*2] + o3[hl*2:hl*3]*c2
#c3 = o3[0:128]*o3[128:256] + c2

h4 = o3[hl*3:hl*4]*cactivate(c3)

y = h4.dot(w4)+w5

y = np.exp(y)/np.sum(np.exp(y))

plt.plot(y,'b-')
plt.show()

En conséquence, vous pouvez voir que preds et y produisent des valeurs similaires.

image2.png résultats du tracé preds

image.png résultat du tracé de y

À propos, le code ci-dessus utilise sigmoïde pour la fonction d'activation et la fonction de cellule interne, mais pour une raison quelconque, il n'a pas fonctionné avec tanh. Je veux mettre à jour quand il est résolu.

Recommended Posts

Décodage du modèle LSTM de Keras.
L'histoire de sys.path.append ()
L'histoire de la construction de Zabbix 4.4
L'histoire de Python et l'histoire de NaN
L'histoire de la participation à AtCoder
L'histoire du "trou" dans le fichier
L'histoire du remontage du serveur d'application
L'histoire de l'exportation d'un programme
L'histoire d'essayer de reconnecter le client
L'histoire d'une erreur dans PyOCR
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
L'histoire de la fabrication d'un moule immuable
L'histoire de la manipulation des variables globales Python
L'histoire d'essayer deep3d et de perdre
L'histoire du traitement A du blackjack (python)
L'histoire du changement de pep8 en pycodestyle
L'histoire de l'apprentissage profond avec TPU
L'histoire selon laquelle le coût d'apprentissage de Python est faible
L'histoire de la création du Mel Icon Generator version 2
Traitement d'image? L'histoire du démarrage de Python pour
L'histoire de la recherche du n optimal dans N poing
L'histoire de la mauvaise lecture de la ligne d'échange de la commande supérieure
L'histoire de la lecture des données HSPICE en Python
L'histoire d'essayer Sourcetrail × macOS × VS Code
L'histoire de l'affichage des fichiers multimédias dans Django
L'histoire de la création d'un générateur d'icônes mel
[Petite histoire] Téléchargez l'image de Ghibli immédiatement
Histoire de passer de Pipenv à la poésie
L'histoire du lancement d'un serveur Minecraft depuis Discord
Une histoire qui réduit l'effort de fonctionnement / maintenance
L'histoire de l'arrêt du service de production avec la commande hostname
L'histoire de la création de l'environnement Linux le plus rapide au monde
L'histoire de l'inadéquation de Hash Sum causée par gcrypto20
Détection d'anomalies des données de séries chronologiques par LSTM (Keras)
L'histoire de la création d'un réseau neuronal de génération musicale
L'histoire de FileNotFound en Python open () mode = 'w'
J'ai vérifié les spécifications de sortie du LSTM bidirectionnel de PyTorch
Une histoire sur le changement du nom principal de BlueZ
Bilan du premier défi du machine learning avec Keras
L'histoire selon laquelle la valeur de retour de tape.gradient () était None
Le problème Zip 4 Gbyte est une histoire du passé
Une histoire qui a analysé la livraison de Nico Nama.
AttributeError: L'histoire de la résolution du module 'Sensorflow' n'a pas d'attribut'log '.
L'histoire de la conversion automatique du langage de TypeScript / JavaScript / Python
L'histoire de vouloir acheter une aventure en forme de bague
L'histoire de l'utilisation de Circleci pour construire des roues Manylinux
Le début de cif2cell
Résumé de Tensorflow / Keras
Le sens de soi
le zen de Python
LSTM multivarié avec Keras
La vengeance des types: la vengeance des types
L'histoire de la création d'un canal VIP dans le chatwork en interne
L'histoire de la mise en œuvre du sujet Facebook Messenger Bot avec python
Sakura L'histoire du fonctionnement de la bouteille Python sur Internet
L'histoire de l'introduction de Jedi (package de complétion automatique de python) dans emacs
J'ai essayé la reconnaissance faciale du problème du rire en utilisant Keras.
L'histoire du champ de modèle Django disparaissant de la classe