redes recurrentes neuronales neuronal ejemplos ejemplo construccion con algoritmo python keras prediction recurrent-neural-network

recurrentes - redes neuronales python



¿Por qué molestarse con las redes neuronales recurrentes para datos estructurados? (1)

He estado desarrollando redes neuronales de avance (FNN) y redes neuronales recurrentes (RNN) en Keras con datos estructurados de la forma [instances, time, features] , y el rendimiento de los FNN y RNN ha sido el mismo (excepto que los RNN requieren más tiempo de cálculo).

También simulé datos tabulares (código a continuación) donde esperaba que un RNN superara a un FNN porque el siguiente valor de la serie depende del valor anterior de la serie; Sin embargo, ambas arquitecturas predicen correctamente.

Con los datos de la PNL, he visto que las RNN superan a las FNN, pero no con los datos tabulares. En general, ¿cuándo se espera que una RNN supere a una FNN con datos tabulares? Específicamente, ¿podría alguien publicar un código de simulación con datos tabulares que demuestren un RNN que supere a un FNN?

¡Gracias! Si mi código de simulación no es ideal para mi pregunta, ¡adáptelo o comparta uno más ideal!

from keras import models from keras import layers from keras.layers import Dense, LSTM import numpy as np import matplotlib.pyplot as plt

Se simularon dos funciones en 10 pasos de tiempo, donde el valor de la segunda función depende del valor de ambas funciones en el paso de tiempo anterior.

## Simulate data. np.random.seed(20180825) X = np.random.randint(50, 70, size = (11000, 1)) / 100 X = np.concatenate((X, X), axis = 1) for i in range(10): X_next = np.random.randint(50, 70, size = (11000, 1)) / 100 X = np.concatenate((X, X_next, (0.50 * X[:, -1].reshape(len(X), 1)) + (0.50 * X[:, -2].reshape(len(X), 1))), axis = 1) print(X.shape) ## Training and validation data. split = 10000 Y_train = X[:split, -1:].reshape(split, 1) Y_valid = X[split:, -1:].reshape(len(X) - split, 1) X_train = X[:split, :-2] X_valid = X[split:, :-2] print(X_train.shape) print(Y_train.shape) print(X_valid.shape) print(Y_valid.shape)

FNN:

## FNN model. # Define model. network_fnn = models.Sequential() network_fnn.add(layers.Dense(64, activation = ''relu'', input_shape = (X_train.shape[1],))) network_fnn.add(Dense(1, activation = None)) # Compile model. network_fnn.compile(optimizer = ''adam'', loss = ''mean_squared_error'') # Fit model. history_fnn = network_fnn.fit(X_train, Y_train, epochs = 10, batch_size = 32, verbose = False, validation_data = (X_valid, Y_valid)) plt.scatter(Y_train, network_fnn.predict(X_train), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.show() plt.scatter(Y_valid, network_fnn.predict(X_valid), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.show()

LSTM:

## LSTM model. X_lstm_train = X_train.reshape(X_train.shape[0], X_train.shape[1] // 2, 2) X_lstm_valid = X_valid.reshape(X_valid.shape[0], X_valid.shape[1] // 2, 2) # Define model. network_lstm = models.Sequential() network_lstm.add(layers.LSTM(64, activation = ''relu'', input_shape = (X_lstm_train.shape[1], 2))) network_lstm.add(layers.Dense(1, activation = None)) # Compile model. network_lstm.compile(optimizer = ''adam'', loss = ''mean_squared_error'') # Fit model. history_lstm = network_lstm.fit(X_lstm_train, Y_train, epochs = 10, batch_size = 32, verbose = False, validation_data = (X_lstm_valid, Y_valid)) plt.scatter(Y_train, network_lstm.predict(X_lstm_train), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.show() plt.scatter(Y_valid, network_lstm.predict(X_lstm_valid), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.show()


En la práctica, incluso en la PNL, se observa que las RNN y las CNN suelen ser competitivas. Here''s un artículo de revisión de 2017 que muestra esto con más detalle. En teoría, podría ser el caso de que las RNN puedan manejar mejor la totalidad de la complejidad y la naturaleza secuencial del lenguaje, pero en la práctica, el mayor obstáculo es entrenar adecuadamente la red y las RNN son meticulosas.

Otro problema que podría tener la posibilidad de funcionar sería ver un problema como el problema del paréntesis equilibrado (ya sea con paréntesis en las cadenas o paréntesis junto con otros personajes distractores). Esto requiere el procesamiento secuencial de las entradas y el seguimiento de algún estado, y puede ser más fácil de aprender con un LSTM que con un FFN.

Actualización: Es posible que algunos datos que parecen secuenciales no tengan que tratarse de forma secuencial. Por ejemplo, incluso si proporciona una secuencia de números para sumar ya que la suma es conmutativa, un FFN funcionará tan bien como un RNN. Esto también podría ser cierto para muchos problemas de salud donde la información dominante no es de naturaleza secuencial. Supongamos que cada año se miden los hábitos de fumar de un paciente. Desde el punto de vista del comportamiento, la trayectoria es importante, pero si está pronosticando si el paciente desarrollará cáncer de pulmón, la predicción estará dominada solo por la cantidad de años que el paciente fumó (tal vez restringido a los últimos 10 años para el FFN).

Por lo tanto, desea hacer que el problema del juguete sea más complejo y requerir tener en cuenta el orden de los datos. Tal vez algún tipo de serie de tiempo simulada, en la que desee predecir si hubo un pico en los datos, pero no le importan los valores absolutos solo sobre la naturaleza relativa del pico.

Actualización2

Modifiqué tu código para mostrar un caso en el que los RNN funcionan mejor. El truco consistía en utilizar una lógica condicional más compleja que se modela de forma más natural en los LSTM que en los FFN. El código está abajo. Para 8 columnas, vemos que FFN entrena en 1 minuto y alcanza una pérdida de validación de 6.3. El LSTM tarda 3 veces más en entrenar, pero su pérdida de validación final es 6 veces menor a 1.06.

A medida que aumentamos el número de columnas, el LSTM tiene una ventaja cada vez mayor, especialmente si agregamos condiciones más complicadas. Para 16 columnas, la pérdida de validación de FFN es 19 (y puede ver más claramente la curva de entrenamiento como no lo es el modelo capaz de ajustar instantáneamente los datos). En comparación, el LSTM tarda 11 veces más en entrenar, pero tiene una pérdida de validación de 0.31, ¡30 veces más pequeña que la FFN! Puedes jugar con matrices aún más grandes para ver hasta dónde se extenderá esta tendencia.

from keras import models from keras import layers from keras.layers import Dense, LSTM import numpy as np import matplotlib.pyplot as plt import matplotlib import time matplotlib.use(''Agg'') np.random.seed(20180908) rows = 20500 cols = 10 # Randomly generate Z Z = 100*np.random.uniform(0.05, 1.0, size = (rows, cols)) larger = np.max(Z[:, :cols/2], axis=1).reshape((rows, 1)) larger2 = np.max(Z[:, cols/2:], axis=1).reshape((rows, 1)) smaller = np.min((larger, larger2), axis=0) # Z is now the max of the first half of the array. Z = np.append(Z, larger, axis=1) # Z is now the min of the max of each half of the array. # Z = np.append(Z, smaller, axis=1) # Combine and shuffle. #Z = np.concatenate((Z_sum, Z_avg), axis = 0) np.random.shuffle(Z) ## Training and validation data. split = 10000 X_train = Z[:split, :-1] X_valid = Z[split:, :-1] Y_train = Z[:split, -1:].reshape(split, 1) Y_valid = Z[split:, -1:].reshape(rows - split, 1) print(X_train.shape) print(Y_train.shape) print(X_valid.shape) print(Y_valid.shape) print("Now setting up the FNN") ## FNN model. tick = time.time() # Define model. network_fnn = models.Sequential() network_fnn.add(layers.Dense(32, activation = ''relu'', input_shape = (X_train.shape[1],))) network_fnn.add(Dense(1, activation = None)) # Compile model. network_fnn.compile(optimizer = ''adam'', loss = ''mean_squared_error'') # Fit model. history_fnn = network_fnn.fit(X_train, Y_train, epochs = 500, batch_size = 128, verbose = False, validation_data = (X_valid, Y_valid)) tock = time.time() print() print(str(''%.2f'' % ((tock - tick) / 60)) + '' minutes.'') print("Now evaluating the FNN") loss_fnn = history_fnn.history[''loss''] val_loss_fnn = history_fnn.history[''val_loss''] epochs_fnn = range(1, len(loss_fnn) + 1) print("train loss: ", loss_fnn[-1]) print("validation loss: ", val_loss_fnn[-1]) plt.plot(epochs_fnn, loss_fnn, ''black'', label = ''Training Loss'') plt.plot(epochs_fnn, val_loss_fnn, ''red'', label = ''Validation Loss'') plt.title(''FNN: Training and Validation Loss'') plt.legend() plt.show() plt.scatter(Y_train, network_fnn.predict(X_train), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.title(''training points'') plt.show() plt.scatter(Y_valid, network_fnn.predict(X_valid), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.title(''valid points'') plt.show() print("LSTM") ## LSTM model. X_lstm_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1) X_lstm_valid = X_valid.reshape(X_valid.shape[0], X_valid.shape[1], 1) tick = time.time() # Define model. network_lstm = models.Sequential() network_lstm.add(layers.LSTM(32, activation = ''relu'', input_shape = (X_lstm_train.shape[1], 1))) network_lstm.add(layers.Dense(1, activation = None)) # Compile model. network_lstm.compile(optimizer = ''adam'', loss = ''mean_squared_error'') # Fit model. history_lstm = network_lstm.fit(X_lstm_train, Y_train, epochs = 500, batch_size = 128, verbose = False, validation_data = (X_lstm_valid, Y_valid)) tock = time.time() print() print(str(''%.2f'' % ((tock - tick) / 60)) + '' minutes.'') print("now eval") loss_lstm = history_lstm.history[''loss''] val_loss_lstm = history_lstm.history[''val_loss''] epochs_lstm = range(1, len(loss_lstm) + 1) print("train loss: ", loss_lstm[-1]) print("validation loss: ", val_loss_lstm[-1]) plt.plot(epochs_lstm, loss_lstm, ''black'', label = ''Training Loss'') plt.plot(epochs_lstm, val_loss_lstm, ''red'', label = ''Validation Loss'') plt.title(''LSTM: Training and Validation Loss'') plt.legend() plt.show() plt.scatter(Y_train, network_lstm.predict(X_lstm_train), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.title(''training'') plt.show() plt.scatter(Y_valid, network_lstm.predict(X_lstm_valid), alpha = 0.1) plt.xlabel(''Actual'') plt.ylabel(''Predicted'') plt.title("validation") plt.show()