Con Keras Python para comprender el estado de la red neuronal recurrente LSTM

    Este artículo es una traducción de la gran [PhD Jason Brownlee] Dios Bowen, la dirección original en aquí .

    

      Después de leer este artículo, usted sabrá:

如何为序列预测问题开发朴素的LSTM网络。
如何使用LSTM网络通过批处理和功能仔细管理状态。
如何在LSTM网络中手动管理状态以进行状态预测。
在我的新书中,用几行代码,通过18个循序渐进的教程和9个项目,探索如何为一系列预测建模问题开发深度学习模型。

 

Descripción del problema: Alfabeto de aprendizaje

       En este tutorial, vamos a desarrollar y comparar muchos LSTM recurrente modelo de red neuronal diferente.

       Estos contexto comparativo sería un simple problema de previsión de serie aprendizaje de las letras. Es decir, dada una carta, para predecir la siguiente letra del alfabeto. Este es un simple problemas de previsión de serie, una vez entendida, pueden extenderse a otros problemas de previsión de serie, como predicción de series de tiempo y clasificación secuencia. Veamos ahora algunas código Python se puede reutilizar entre los ejemplos para preparar preguntas. En primer lugar, vamos a importar todas las clases y funciones que planea utilizar en este tutorial.

import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils

       A continuación, nos puede proporcionar semilla para el generador de números aleatorios para asegurarse de que el código se ejecuta cada vez que los resultados son los mismos.

# fix random seed for reproducibility
numpy.random.seed(7)

       Ahora, podemos definir un conjunto de datos de esa carta. Para facilitar la lectura, vamos a definir las letras en mayúsculas. modelado de la red neuronal digital, por lo que necesitamos para trazar las letras es un entero. Podemos crear un índice por carta a los personajes del diccionario (mapa) para lograr fácilmente esto. También podemos crear una búsqueda inversa para volver a convertir predicción de caracteres para su uso posterior.

# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))

      Ahora, tenemos que crear entradas y salidas, en las que entrenan a nuestra red neuronal. Podemos definir la longitud de la secuencia de entrada, y luego leer en secuencia de la secuencia de letras de entrada para hacer esto. Por ejemplo, utilizamos una longitud de entrada. Desde el principio de los datos de entrada originales, podemos leer la primera letra "A", como la predicción y la siguiente letra "B". Predecimos el movimiento y repetir hasta que la "Z" a lo largo de un personaje.

# prepare the dataset of input to output pairs encoded as integers
seq_length = 1
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)

       También vamos a imprimir de entrada para la comprobación de integridad. Esto ejecutará código para generar la salida siguiente, un resumen de la longitud de la secuencia de entrada y da salida a un solo carácter.

A -> B
B -> C
C -> D
D -> E
E -> F
F -> G
G -> H
H -> I
I -> J
J -> K
K -> L
L -> M
M -> N
N -> O
O -> P
P -> Q
Q -> R
R -> S
S -> T
T -> U
U -> V
V -> W
W -> X
X -> Y
Y -> Z

       Necesitamos gama NumPy remodelación de la red LSTM formato, es decir deseado: [ las muestras, pasos de tiempo, características ].

# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), seq_length, 1))

      Después de la conformación, podemos introducir un número entero normalizado a la gama de 0 a 1, es decir, el uso de S-en forma de gama LSTM red de funciones de activación.

# normalize
X = X / float(len(alphabet))

      Por último, podemos utilizar este tema como una tarea de clasificación de secuencias, donde cada letra representa 26 letras en una clase diferente. Por lo tanto, podemos utilizar la función incorporada de to_categorical Keras () de salida (y) se convierte en una sola caliente de codificación.

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

Para un personaje de aprender un simple LSTM asignación de caracteres

         Diseño Vayamos un simple inicio LSTM para aprender a predecir el siguiente carácter en el alfabeto en el contexto dado de un personaje. cuestión que se construye como una sola carta a un conjunto aleatorio de entrada de una sola salida letra. Como veremos, esto es LSTM aprendizaje difícil. Se define un LSTM red 32 unidades y una capa de salida que tiene una función de activación softmax tiene que ser predicho. Debido a que este es un problema de clasificación con varias categorías, por lo que podemos usar una función de pérdida logarítmica (llamado "categorical_crossentropy" en Keras in), y el uso de la función de optimización de ADAM para optimizar la red. El modelo para 500 era, el tamaño del lote es 1.

# create and fit the model
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], X.shape[2])))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=500, batch_size=1, verbose=2)

       Después de ajustar el modelo, podemos evaluar y resumir el rendimiento de todo el conjunto de datos de entrenamiento.

# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))

        Entonces, podemos volver a ejecutar el banco de datos de la red y genera predicciones, la entrada y salida de los personajes están de vuelta convertida a su formato original para entender intuitivamente la extensión de la red para entender el problema.

# demonstrate some model predictions
for pattern in dataX:
	x = numpy.reshape(pattern, (1, len(pattern), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

      La implementación del código completo es el siguiente:

# Naive LSTM to learn one-char to one-char mapping
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
seq_length = 1
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), seq_length, 1))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], X.shape[2])))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=500, batch_size=1, verbose=2)
# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
for pattern in dataX:
	x = numpy.reshape(pattern, (1, len(pattern), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

      resultados de salida Realiza son los siguientes:

Model Accuracy: 84.00%
['A'] -> B
['B'] -> C
['C'] -> D
['D'] -> E
['E'] -> F
['F'] -> G
['G'] -> H
['H'] -> I
['I'] -> J
['J'] -> K
['K'] -> L
['L'] -> M
['M'] -> N
['N'] -> O
['O'] -> P
['P'] -> Q
['Q'] -> R
['R'] -> S
['S'] -> T
['T'] -> U
['U'] -> W
['V'] -> Y
['W'] -> Z
['X'] -> Z
['Y'] -> Z

       Podemos ver que la red es, en efecto difícil de resolver este problema. La razón es que no hay medios contexto LSTM inferior puede ser utilizado. Cada entrada - modo de salida se muestran en un orden aleatorio a la red, y en cada modo (en cada modo por lotes, cada lote que comprende a) restablecer el estado de la red. Esto es un abuso de la arquitectura de red LSTM, se le trata como estándar Perceptrón multicapa misma. A continuación, vamos a tratar de definir el problema de manera diferente, con el fin de proporcionar orden más el aprendizaje de la red.

LSTM un simple ventana de funciones de tres caracteres a una asignación de caracteres

       Añadir más contexto para la multicapa datos perceptrón método popular es utilizar un método de la ventana. Aquí es donde la secuencia de la etapa anterior como otra función de entrada proporcionada por la red. Podemos tratar de utilizar la misma técnica para proporcionar más contexto para la red LSTM. Aquí, la longitud de la secuencia será de 1 a 3, por ejemplo:

# prepare the dataset of input to output pairs encoded as integers
seq_length = 3

      El entrenamiento de ejemplos de datos son los siguientes:

ABC -> D
BCD -> E
CDE -> F

       A continuación, cada elemento en la secuencia como una nueva función a la entrada de red. Esto requiere la modificación de la secuencia de entrada de una manera remodelación de pasos de preparación de datos:

# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), 1, seq_length))

        También necesita ser modificado con el fin de demostrar que en el momento calculado a partir del modelo de cómo formar de nuevo modelo de la muestra.

x = numpy.reshape(pattern, (1, 1, len(pattern)))

       la implementación del código completo es el siguiente:

# Naive LSTM to learn three-char window to one-char mapping
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
seq_length = 3
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), 1, seq_length))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], X.shape[2])))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=500, batch_size=1, verbose=2)
# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
for pattern in dataX:
	x = numpy.reshape(pattern, (1, 1, len(pattern)))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

        resultados de salida Realiza son los siguientes:

Model Accuracy: 86.96%
['A', 'B', 'C'] -> D
['B', 'C', 'D'] -> E
['C', 'D', 'E'] -> F
['D', 'E', 'F'] -> G
['E', 'F', 'G'] -> H
['F', 'G', 'H'] -> I
['G', 'H', 'I'] -> J
['H', 'I', 'J'] -> K
['I', 'J', 'K'] -> L
['J', 'K', 'L'] -> M
['K', 'L', 'M'] -> N
['L', 'M', 'N'] -> O
['M', 'N', 'O'] -> P
['N', 'O', 'P'] -> Q
['O', 'P', 'Q'] -> R
['P', 'Q', 'R'] -> S
['Q', 'R', 'S'] -> T
['R', 'S', 'T'] -> U
['S', 'T', 'U'] -> V
['T', 'U', 'V'] -> Y
['U', 'V', 'W'] -> Z
['V', 'W', 'X'] -> Z
['W', 'X', 'Y'] -> Z

       Podemos ver que, para mejorar la tasa de rendimiento no puede, o no. Esta es una cuestión sencilla, incluso con el método de la ventana, todavía no se puede aprender por LSTM. Una vez más, se trata de un marco pobres en el tema del abuso de la red LSTM. De hecho, la secuencia de letras es un paso de tiempo característico, en lugar de una sola vez las características de longitud de paso. Proporcionamos más contexto para la red, pero no ya que hay más orden como se esperaba.

      En la siguiente sección, vamos a estar en la forma de paso de tiempo para proporcionar más información de base para la red.

LSTM sencillos pasos para una ventana de tiempo de tres caracteres a una asignación de caracteres

        En Keras en, LSTM uso previsto es en forma de pasos de tiempo proporcionan contexto, más que las otras redes ofrecen el mismo tipo de función de ventana. Podemos dar un primer ejemplo, la longitud de la secuencia simplemente cambiado de 1 a 3.

seq_length = 3
输入-输出样例如下所示:
ABC -> D
BCD -> E
CDE -> F
DEF -> G

     Excepto que la remodelación de la secuencia de datos de entrada como una serie de tiempo de un paso característica, en lugar de un solo paso de tiempo de la pluralidad de elementos.

# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), seq_length, 1))

      la implementación del código completo es el siguiente:

# Naive LSTM to learn three-char time steps to one-char mapping
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
seq_length = 3
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), seq_length, 1))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], X.shape[2])))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=500, batch_size=1, verbose=2)
# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
for pattern in dataX:
	x = numpy.reshape(pattern, (1, len(pattern), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

       resultados de salida Realiza son los siguientes:

Model Accuracy: 100.00%
['A', 'B', 'C'] -> D
['B', 'C', 'D'] -> E
['C', 'D', 'E'] -> F
['D', 'E', 'F'] -> G
['E', 'F', 'G'] -> H
['F', 'G', 'H'] -> I
['G', 'H', 'I'] -> J
['H', 'I', 'J'] -> K
['I', 'J', 'K'] -> L
['J', 'K', 'L'] -> M
['K', 'L', 'M'] -> N
['L', 'M', 'N'] -> O
['M', 'N', 'O'] -> P
['N', 'O', 'P'] -> Q
['O', 'P', 'Q'] -> R
['P', 'Q', 'R'] -> S
['Q', 'R', 'S'] -> T
['R', 'S', 'T'] -> U
['S', 'T', 'U'] -> V
['T', 'U', 'V'] -> W
['U', 'V', 'W'] -> X
['V', 'W', 'X'] -> Y
['W', 'X', 'Y'] -> Z

      Podemos ver un ejemplo de modelo de evaluación y predicción demuestra que el modelo puede perfectamente los problemas de aprendizaje. Pero ha aprendido una pregunta más sencilla. En concreto, se supo que la secuencia predicha a partir de tres letras del alfabeto de la letra siguiente. Alfabeto puede aparecer en cualquier secuencia aleatoria de tres letras, y predecir la siguiente letra. En realidad, no puede ser letras enumerados. Espero tener una ventana lo suficientemente grande red Perceptrón multicapa puede utilizar el mismo método para aprender el mapa. LSTM red es con estado. Deben ser capaces de aprender toda la secuencia de letras, pero por defecto, Keras realización se restablezca el estado de la red después de cada entrenamiento por lotes.

Estado LSTM de lotes

      Después de cada lote de lote, LSTM de Keras realización restablecerá el estado de la red. Esto demuestra que si el tamaño del lote suficiente para dar cabida a todos los modos de entrada, y todos los modos de entrada se clasifican en orden, que puede utilizar la secuencia de lotes contexto LSTM para aprender mejor la secuencia. El primer ejemplo de aprendizaje a través de una cartografía de los cambios y para el aumento de tamaño del lote desde el tamaño de un conjunto de datos de entrenamiento, se puede demostrar fácilmente. Además, Keras estará en el conjunto de datos de entrenamiento barajan antes de cada época de entrenamiento. Con el fin de garantizar el modo de datos de entrenamiento para mantener el orden, podemos desactivar la reproducción aleatoria.

model.fit(X, y, epochs=5000, batch_size=len(dataX), verbose=2, shuffle=False)

      Mapeo de la red va a utilizar la secuencia de aprendizaje lote de caracteres, pero durante la predicción, el contexto no estará disponible en la red. Podemos evaluar la capacidad de la red para predecir aleatoria y secuencial.

    La ejecución general código es el siguiente:

# Naive LSTM to learn one-char to one-char mapping with all data in each batch
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
from keras.preprocessing.sequence import pad_sequences
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
seq_length = 1
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)
# convert list of lists to array and pad sequences if needed
X = pad_sequences(dataX, maxlen=seq_length, dtype='float32')
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (X.shape[0], seq_length, 1))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
model = Sequential()
model.add(LSTM(16, input_shape=(X.shape[1], X.shape[2])))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=5000, batch_size=len(dataX), verbose=2, shuffle=False)
# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
for pattern in dataX:
	x = numpy.reshape(pattern, (1, len(pattern), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)
# demonstrate predicting random patterns
print("Test a Random Pattern:")
for i in range(0,20):
	pattern_index = numpy.random.randint(len(dataX))
	pattern = dataX[pattern_index]
	x = numpy.reshape(pattern, (1, len(pattern), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

       resultados de salida Realiza son los siguientes:

Model Accuracy: 100.00%
['A'] -> B
['B'] -> C
['C'] -> D
['D'] -> E
['E'] -> F
['F'] -> G
['G'] -> H
['H'] -> I
['I'] -> J
['J'] -> K
['K'] -> L
['L'] -> M
['M'] -> N
['N'] -> O
['O'] -> P
['P'] -> Q
['Q'] -> R
['R'] -> S
['S'] -> T
['T'] -> U
['U'] -> V
['V'] -> W
['W'] -> X
['X'] -> Y
['Y'] -> Z
Test a Random Pattern:
['T'] -> U
['V'] -> W
['M'] -> N
['Q'] -> R
['D'] -> E
['V'] -> W
['T'] -> U
['U'] -> V
['J'] -> K
['F'] -> G
['N'] -> O
['B'] -> C
['M'] -> N
['F'] -> G
['F'] -> G
['P'] -> Q
['A'] -> B
['K'] -> L
['W'] -> X
['E'] -> F

        Tal y como esperábamos, la red se puede utilizar en el contexto de la secuencia de aprendizaje de las letras, con el fin de lograr el 100% de precisión en los datos de entrenamiento. Es importante destacar que la red puede predecir con exactitud la siguiente letra del alfabeto carácter seleccionado al azar. Muy impresionante.

Con estado LSTM, para la asignación de un personaje a personaje 1

     Hemos visto que podemos ser los datos brutos en una secuencia de tamaño fijo, y LSTM podemos aprender esta representación, pero sólo podemos aprender tres caracteres aleatorios para asignar un carácter. También vemos que podemos hacer la metamorfosis tamaño del lote, con el fin de ofrecer más series para la cadena, pero sólo durante el entrenamiento. Idealmente, queremos exponer la red a toda la secuencia, y dejar que se aprenda la interdependencia, en lugar de definir explícitamente las dependencias en el marco de cuestiones. Podemos hacerlo en Keras de esta manera es hacer que la capa LSTM convertirse en estado, y el final del período (es decir, al final de la secuencia de entrenamiento) para reiniciar manualmente el estado de la red.

      Esto es realmente va a LSTM manera de utilizar la red. En primer lugar, la necesidad de capa LSTM se define como un estado. Al hacer esto, hay que especificar explícitamente el tamaño del tamaño del lote como la forma de entrada. Esto también significa que cuando evaluamos la red o hacer predicciones, también hay que especificar y cumplir con el mismo tamaño de lote. Ahora bien, esto no es un problema, porque estamos utilizando el tamaño del lote es de 1. Este puede ser el tamaño del lote difícil predecir cuándo el caso 1 no es, debido a la necesidad de predecir y el orden en lotes.

batch_size = 1
model.add(LSTM(50, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True))

       Hay una diferencia importante entre LSTM nivel de entrenamiento, que de forma manual una vez por período de entrenamiento, y el estado de reinicio después de cada período. Podemos hacer esto en un bucle. Una vez más, no barajar de entrada, pero para mantener el orden de la creación de datos de entrenamiento de entrada.

for i in range(300):
	model.fit(X, y, epochs=1, batch_size=batch_size, verbose=2, shuffle=False)
	model.reset_states()

       Como se describió anteriormente, el tamaño del lote específico se evalúa el rendimiento de red en todo el conjunto de datos de entrenamiento.

# summarize performance of the model
scores = model.evaluate(X, y, batch_size=batch_size, verbose=0)
model.reset_states()
print("Model Accuracy: %.2f%%" % (scores[1]*100))

       Por último, podemos probar que la red realmente aprendió el alfabeto completo. Podemos utilizar la primera letra "A", como una semilla, una solicitud para la predicción, la predicción es realimentada como una entrada, hasta que se repita todo el proceso de "Z".

# demonstrate some model predictions
seed = [char_to_int[alphabet[0]]]
for i in range(0, len(alphabet)-1):
	x = numpy.reshape(seed, (1, len(seed), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	print(int_to_char[seed[0]], "->", int_to_char[index])
	seed = [index]
model.reset_states()

        También podemos ver si la red puede predecirse a partir del comienzo de cualquier carta.

# demonstrate a random starting point
letter = "K"
seed = [char_to_int[letter]]
print("New start: ", letter)
for i in range(0, 5):
	x = numpy.reshape(seed, (1, len(seed), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	print(int_to_char[seed[0]], "->", int_to_char[index])
	seed = [index]
model.reset_states()

       la implementación del código completo es el siguiente:

# Stateful LSTM to learn one-char to one-char mapping
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
seq_length = 1
dataX = []
dataY = []
for i in range(0, len(alphabet) - seq_length, 1):
	seq_in = alphabet[i:i + seq_length]
	seq_out = alphabet[i + seq_length]
	dataX.append([char_to_int[char] for char in seq_in])
	dataY.append(char_to_int[seq_out])
	print(seq_in, '->', seq_out)
# reshape X to be [samples, time steps, features]
X = numpy.reshape(dataX, (len(dataX), seq_length, 1))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
batch_size = 1
model = Sequential()
model.add(LSTM(50, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
for i in range(300):
	model.fit(X, y, epochs=1, batch_size=batch_size, verbose=2, shuffle=False)
	model.reset_states()
# summarize performance of the model
scores = model.evaluate(X, y, batch_size=batch_size, verbose=0)
model.reset_states()
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
seed = [char_to_int[alphabet[0]]]
for i in range(0, len(alphabet)-1):
	x = numpy.reshape(seed, (1, len(seed), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	print(int_to_char[seed[0]], "->", int_to_char[index])
	seed = [index]
model.reset_states()
# demonstrate a random starting point
letter = "K"
seed = [char_to_int[letter]]
print("New start: ", letter)
for i in range(0, 5):
	x = numpy.reshape(seed, (1, len(seed), 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	print(int_to_char[seed[0]], "->", int_to_char[index])
	seed = [index]
model.reset_states()

      resultados de salida Realiza son los siguientes:
 

Model Accuracy: 100.00%
A -> B
B -> C
C -> D
D -> E
E -> F
F -> G
G -> H
H -> I
I -> J
J -> K
K -> L
L -> M
M -> N
N -> O
O -> P
P -> Q
Q -> R
R -> S
S -> T
T -> U
U -> V
V -> W
W -> X
X -> Y
Y -> Z
New start:  K
K -> B
B -> C
C -> D
D -> E
E -> F

      Podemos ver la red recordar perfectamente todo el alfabeto. Utiliza el contexto de la propia muestra, y entender las dependencias predecir la siguiente secuencia de caracteres necesarios. También podemos ver, si utilizamos la primera letra de la red como una semilla, se puede establecer correctamente un lado el caos del resto del alfabeto. También podemos ver que sólo tuvo conocimiento de la secuencia completa de las letras, y es un popular desde el comienzo del aprendizaje. Cuando se le preguntó para predecir la siguiente letra "K" en, será predecir el "B" y volver a todo el alfabeto. Con el fin de predecir el verdadero "K", se requiere un estado de la red iterativo precalentado a partir de "A" a "J" representa una letra. Esto nos dice que a través de los siguientes datos de entrenamiento, podemos utilizar el LSTM "sin estado" lograr el mismo efecto:

---a -> b
--ab -> c
-abc -> d
abcd -> e

     25 se fija a la secuencia de entrada (de Y a un z predicción), y el modo de prefijo relleno de ceros. Por último, plantean cuestiones menores secuencia de entrada de longitud variable para predecir un carácter a la red LSTM tren.

Entrada a un LSTM salida de caracteres de longitud variable

      En la sección anterior, encontramos Keras "con estado" antes LSTM es realmente sólo un atajo n repetición de secuencias, pero en realidad no nos ayuda a aprender las letras modelo general.

En esta sección, se explora la "sin estado" LSTM una variante, la secuencia aleatoria variantes de aprender el alfabeto, y nos esforzamos para construir un modelo de cualquier carta o secuencias se pueden dar y predecir la siguiente letra del abecedario letras. En primer lugar, estamos marco para el cambio. Por simplicidad, vamos a definir la longitud máxima de la secuencia de entrada y se ajusta a un valor pequeño de 5 o similar, con el fin de acelerar la formación. Esto define la longitud máxima de las secuencias de letras para ser entrenado. En la extensión, si permitimos que vuelve de nuevo al comienzo de la secuencia, puede configurarlo para que todo el alfabeto (26) o más. También tenemos que definir el número de secuencias aleatorias que se cree, en este caso 1000. Esto puede ser más o menos. Quiero realmente necesitan menos de modo.

# prepare the dataset of input to output pairs encoded as integers
num_inputs = 1000
max_len = 5
dataX = []
dataY = []
for i in range(num_inputs):
	start = numpy.random.randint(len(alphabet)-2)
	end = numpy.random.randint(start, min(start+max_len,len(alphabet)-1))
	sequence_in = alphabet[start:end+1]
	sequence_out = alphabet[end + 1]
	dataX.append([char_to_int[char] for char in sequence_in])
	dataY.append(char_to_int[sequence_out])
	print(sequence_in, '->', sequence_out)

       muestra de entrada de la siguiente manera:

PQRST -> U
W -> X
O -> P
OPQ -> R
IJKLM -> N
QRSTU -> V
ABCD -> E
X -> Y
GHIJ -> K

       La longitud de la secuencia de entrada varía entre 1 a max_len, se requiere relleno de ceros. Aquí, nosotros usamos las pad_sequences construidos () se llena función en el lado izquierdo de Keras (prefijo).

X = pad_sequences(dataX, maxlen=max_len, dtype='float32')

       La evaluación del modelo de formación sobre el modo de entrada seleccionada al azar. Es tan fácil como una nueva secuencia generada de forma aleatoria de caracteres. También creo que esto también puede ser una secuencia lineal de "A", como una semilla, que devuelven un solo fes de salida de entrada de caracteres.

      la implementación del código completo es el siguiente:

# LSTM with Variable Length Input Sequences to One Character Output
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
from keras.preprocessing.sequence import pad_sequences
from theano.tensor.shared_randomstreams import RandomStreams
# fix random seed for reproducibility
numpy.random.seed(7)
# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# prepare the dataset of input to output pairs encoded as integers
num_inputs = 1000
max_len = 5
dataX = []
dataY = []
for i in range(num_inputs):
	start = numpy.random.randint(len(alphabet)-2)
	end = numpy.random.randint(start, min(start+max_len,len(alphabet)-1))
	sequence_in = alphabet[start:end+1]
	sequence_out = alphabet[end + 1]
	dataX.append([char_to_int[char] for char in sequence_in])
	dataY.append(char_to_int[sequence_out])
	print(sequence_in, '->', sequence_out)
# convert list of lists to array and pad sequences if needed
X = pad_sequences(dataX, maxlen=max_len, dtype='float32')
# reshape X to be [samples, time steps, features]
X = numpy.reshape(X, (X.shape[0], max_len, 1))
# normalize
X = X / float(len(alphabet))
# one hot encode the output variable
y = np_utils.to_categorical(dataY)
# create and fit the model
batch_size = 1
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], 1)))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, y, epochs=500, batch_size=batch_size, verbose=2)
# summarize performance of the model
scores = model.evaluate(X, y, verbose=0)
print("Model Accuracy: %.2f%%" % (scores[1]*100))
# demonstrate some model predictions
for i in range(20):
	pattern_index = numpy.random.randint(len(dataX))
	pattern = dataX[pattern_index]
	x = pad_sequences([pattern], maxlen=max_len, dtype='float32')
	x = numpy.reshape(x, (1, max_len, 1))
	x = x / float(len(alphabet))
	prediction = model.predict(x, verbose=0)
	index = numpy.argmax(prediction)
	result = int_to_char[index]
	seq_in = [int_to_char[value] for value in pattern]
	print(seq_in, "->", result)

        La salida de resultados es el siguiente:

Model Accuracy: 98.90%
['Q', 'R'] -> S
['W', 'X'] -> Y
['W', 'X'] -> Y
['C', 'D'] -> E
['E'] -> F
['S', 'T', 'U'] -> V
['G', 'H', 'I', 'J', 'K'] -> L
['O', 'P', 'Q', 'R', 'S'] -> T
['C', 'D'] -> E
['O'] -> P
['N', 'O', 'P'] -> Q
['D', 'E', 'F', 'G', 'H'] -> I
['X'] -> Y
['K'] -> L
['M'] -> N
['R'] -> T
['K'] -> L
['E', 'F', 'G'] -> H
['Q'] -> R
['Q', 'R', 'S'] -> T

       Podemos ver que, aunque el modelo no está perfectamente aprendió el alfabeto de secuencias generadas aleatoriamente en, pero es un muy buen efecto. El modelo no ha sido ajustado, puede necesitar más formación o redes más grandes, o ambos (es un ejercicio para el lector). Esto es en la parte superior de aprendizaje "todo en orden de la hornada ejemplo de entrada de" buena extensión natural de modelos de cartas, porque puede manejar ad hoc consultas, pero esto es la secuencia de longitud arbitraria (longitud máxima).

resumen

       En este artículo, se encuentra en Keras LSTM Son recurrentes las redes neuronales y cómo se las arreglan estado. Específicamente, usted aprenderá:

如何为单个字符到一个字符的预测开发幼稚的LSTM网络。
如何配置朴素的LSTM以学习样本中各个时间步长的序列。
如何配置LSTM以通过手动管理状态来学习样本之间的序列。

 

Publicados 532 artículos originales · ganado elogios 1297 · Vistas 3,34 millones +

Supongo que te gusta

Origin blog.csdn.net/Together_CZ/article/details/104873595
Recomendado
Clasificación