Las redes neuronales recurrentes (RNN) están ganando mucha atención en los últimos años porque se han mostrado muy prometedoras en muchas tareas de procesamiento del lenguaje natural. A pesar de su popularidad, hay un número limitado de tutoriales que explican cómo implementar una aplicación sencilla e interesante utilizando herramientas de última generación. En esta serie, utilizaremos una red neuronal recurrente para entrenar a un programador de IA, que puede escribir código Java como un programador real (con suerte). Se cubrirá lo siguiente:
1. Construyendo un programador de IA simple
2. Mejora del programador de IA: uso de tokens
3. Mejora del programador de IA: uso de diferentes estructuras de red (esta publicación)
En las publicaciones anteriores, creamos un programador de IA básico usando personajes y tokens como datos de entrenamiento, respectivamente. Ambos enfoques utilizan una red neuronal LSTM simple de 1 capa. Más específicamente, la red utiliza una estructura de muchos a uno, como se muestra en el siguiente diagrama:
Para las predicciones de secuencia a secuencia, existen otras estructuras como uno a muchos y muchos a muchos. En esta publicación, implementaremos una estructura de red simple de muchos a muchos como la siguiente. El código se envía al mismo repositorio en GitHub (el enlace se proporciona al final de esta publicación).
Dado que la mayor parte del código es el mismo que en la publicación anterior, solo resalto las diferencias aquí.
1. Prepara los datos de entrenamiento
Dado que esta vez predeciremos una secuencia en lugar del siguiente token, la y también debería ser una secuencia. y es la secuencia desplazada a la izquierda en uno desde X.
NUM_INPUT_TOKENS = 10 step = 3 sequences = [] for i in range(0, len(tokenized) - NUM_INPUT_TOKENS-1, step): sequences.append(tokenized[i: i + NUM_INPUT_TOKENS+1]) print('# of training sequences:', len(sequences)) X_temp = np.zeros((len(sequences), NUM_INPUT_TOKENS + 1, len(uniqueTokens)), dtype=np.bool) X = np.zeros((len(sequences), NUM_INPUT_TOKENS, len(uniqueTokens)), dtype=np.bool) y = np.zeros((len(sequences), NUM_INPUT_TOKENS, len(uniqueTokens)), dtype=np.bool) for i, sequence in enumerate(sequences): for t, char in enumerate(sequence): X_temp[i, t, token_indices[char]] = 1 num_sequences = len(X_temp) for i, vec in enumerate(X_temp): y[i] = vec[1:] X[i]= vec[:-1] |
2. Construya una red neuronal recurrente de muchos a muchos
Aquí está el código para construir una red recurrente de muchos a muchos.
model = Sequential() model.add(LSTM(128, input_shape=(NUM_INPUT_TOKENS, len(uniqueTokens)), return_sequences=True)) model.add(TimeDistributed(Dense(len(uniqueTokens)))) model.add(Activation('softmax')) optimizer = RMSprop(lr=0.01) model.compile(loss='categorical_crossentropy', optimizer=optimizer) print(model.summary()) |
Puede imprimir la estructura de la red:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_1 (LSTM) (None, 10, 128) 670208 _________________________________________________________________ time_distributed_1 (TimeDist (None, 10, 1180) 152220 _________________________________________________________________ activation_1 (Activation) (None, 10, 1180) 0 =================================================================
Al igual que hicimos con la estructura de muchos a uno, también podemos apilar fácilmente una capa más de LSTM como se muestra a continuación:
model = Sequential() model.add(LSTM(128, return_sequences=True, input_shape=(NUM_INPUT_TOKENS, len(uniqueTokens)))) model.add(LSTM(128, return_sequences=True)) model.add(TimeDistributed(Dense(len(uniqueTokens)))) model.add(Activation('softmax')) optimizer = RMSprop(lr=0.01) model.compile(loss='categorical_crossentropy', optimizer=optimizer) print(model.summary()) |
La estructura de la red es así:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_1 (LSTM) (None, 10, 128) 670208 _________________________________________________________________ lstm_2 (LSTM) (None, 10, 128) 131584 _________________________________________________________________ time_distributed_1 (TimeDist (None, 10, 1180) 152220 _________________________________________________________________ activation_1 (Activation) (None, 10, 1180) 0 =================================================================
3. Resultados
Los resultados se ven mejor que la red anterior de varios a uno después de solo unas pocas iteraciones. Le recomiendo encarecidamente que ejecute el código y tenga sus propias observaciones y piense en la razón. Sería un buen ejercicio.
runattributes = numberelements [ i ] . offsets [ currindex ] ; patternentry ucompactintarray ; import sun . util . oldstart ;
4. ¿Qué sigue?
En esta publicación, utilicé una red de estructura de muchos a muchos para entrenar el modelo y el modelo predice secuencias de tokens. Quizás por diversión, también puede probar la red uno a varios. Consulte esta tabla para ver otras estructuras de red. Además, hay muchos otros parámetros que podemos ajustar para hacer que el entrenamiento sea más rápido y mejorar el Programador de IA.
Código fuente
1) El código fuente de esta publicación es lstm_ai_coder_tokens_many2many.py que se encuentra en https://github.com/ryanlr/RNN-AI-Programmer