Búsqueda de hiperparámetros para LSTM-RNN usando Keras (Python)

18

De Keras RNN Tutorial: "Los RNN son complicados. La elección del tamaño del lote es importante, la elección de la pérdida y el optimizador es crítica, etc. Algunas configuraciones no convergen".

Entonces, esta es una pregunta más general sobre cómo ajustar los hiperparámetros de un LSTM-RNN en Keras. Me gustaría saber acerca de un enfoque para encontrar los mejores parámetros para su RNN.

Comencé con el ejemplo de IMDB en Keras 'Github .

el modelo principal se ve así:

(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features,
                                                      test_split=0.2)

max_features = 20000
maxlen = 100  # cut texts after this number of words (among top max_features most common words)
batch_size = 32

model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(LSTM(128))  
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy',
          optimizer='adam',
          class_mode="binary")

print("Train...")
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=3,
      validation_data=(X_test, y_test), show_accuracy=True)
score, acc = model.evaluate(X_test, y_test,
                        batch_size=batch_size,
                        show_accuracy=True)

print('Test accuracy:', acc)
Test accuracy:81.54321846

81.5 es un puntaje justo y, lo que es más importante, significa que el modelo, aunque no está completamente optimizado, funciona.

Mis datos son series temporales y la tarea es predicción binaria, igual que en el ejemplo. Y ahora mi problema se ve así:

#Training Data
train = genfromtxt(os.getcwd() + "/Data/trainMatrix.csv", delimiter=',', skip_header=1)
validation = genfromtxt(os.getcwd() + "/Data/validationMatrix.csv", delimiter=',', skip_header=1)

#Targets
miniTrainTargets = [int(x) for x in genfromtxt(os.getcwd() + "/Data/trainTarget.csv", delimiter=',', skip_header=1)]
validationTargets = [int(x) for x in genfromtxt(os.getcwd() + "/Data/validationTarget.csv", delimiter=',', skip_header=1)]

#LSTM
model = Sequential()
model.add(Embedding(train.shape[0], 64, input_length=train.shape[1]))
model.add(LSTM(64)) 
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy',
          optimizer='adam',
          class_mode="binary")

model.fit(train, miniTrainTargets, batch_size=batch_size, nb_epoch=5,
      validation_data=(validation, validationTargets), show_accuracy=True)
valid_preds = model.predict_proba(validation, verbose=0)
roc = metrics.roc_auc_score(validationTargets, valid_preds)
print("ROC:", roc)
ROC:0.5006526

El modelo es básicamente el mismo que el IMDB. Aunque el resultado significa que no está aprendiendo nada. Sin embargo, cuando uso un MLP-NN de vainilla no tengo el mismo problema, el modelo aprende y la puntuación aumenta. Intenté aumentar el número de épocas y aumentar-disminuir el número de unidades LTSM pero la puntuación no aumentará.

Por lo tanto, me gustaría conocer un enfoque estándar para ajustar la red porque, en teoría, el algoritmo debería funcionar mejor que una red de perceptrón multicapa, especialmente para los datos de esta serie de tiempo.

wacax
fuente
1
¿Cuántos datos tienes? ¿Cuál es la longitud de tus secuencias? Los LSTM son realmente útiles para problemas con muchos datos y dependencias a largo plazo.
pir
La búsqueda aleatoria o la optimización bayesiana son formas estándar de encontrar hiperparámetros :)
pir
1
¿Estás seguro de que necesitas la capa de incrustación? Muchos conjuntos de datos de series temporales no lo necesitarían.
pir
Tengo casi 100k puntos de datos y el doble de funciones que el ejemplo IMDB, así que no creo que ese sea el problema. En cuanto a la capa de incrustación, ¿cómo conectaría exactamente la capa LSTM a la entrada? De acuerdo con la documentación keras.io/layers/recurrent/#lstm Keras 'LSTM solo toma inicializaciones, activaciones y output_dim como argumentos. Si esa es la fuente del error, se apreciará enormemente el código que describe cómo eliminar la capa de inclusión.
wacax
Por favor mira mi respuesta. Parece que no necesitas la capa de inserción.
pir

Respuestas:

5

Una capa de incrustación convierte enteros positivos (índices) en vectores densos de tamaño fijo. Por ejemplo, [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]. Esta conversión de representación se aprende automáticamente con la capa de incrustación en Keras (consulte la documentación ).

Sin embargo, parece que sus datos no necesitan ninguna capa de incrustación para realizar una conversión. Tener una capa de incrustación innecesaria es probable por qué no puede hacer que su LSTM funcione correctamente. Si ese es el caso, simplemente debe eliminar la capa de incrustación.

La primera capa de su red debería tener el input_shapeargumento agregado con información sobre las dimensiones de sus datos (ver ejemplos ). Tenga en cuenta que puede agregar este argumento a cualquier capa; no estará presente en la documentación de ninguna capa específica.


Por cierto, los hiperparámetros a menudo se ajustan mediante búsqueda aleatoria u optimización bayesiana. Usaría RMSProp y me enfocaría en ajustar el tamaño del lote (tamaños como 32, 64, 128, 256 y 512), recorte de gradiente (en el intervalo 0.1-10) y abandono (en el intervalo de 0.1-0.6). Los detalles, por supuesto, dependen de los datos y la arquitectura del modelo.

pir
fuente
¿Con qué propone reemplazar la capa de inclusión? Intenté simplemente eliminar la capa de incrustación, pero eso no funciona.
wacax
1
Mire los otros ejemplos: comience, por ejemplo, directamente con la capa Densa. Recuerde configurar el parámetro input_shape.
pir
5

Recomendaría la optimización bayesiana para la búsqueda de hiperparámetros y obtuve buenos resultados con Spearmint. https://github.com/HIPS/Spearmint Es posible que deba usar una versión anterior para uso comercial.

Mutian Zhai
fuente
2

Sugeriría usar hyperopt ( https://github.com/hyperopt/hyperopt ), que usa una especie de optimización bayesiana para buscar valores óptimos de hiperparámetros dada la función objetivo. Es más intuitivo de usar que Spearmint.

PD: hay una envoltura de hipermetropía específicamente para keras, hyperas ( https://github.com/maxpumperla/hyperas ). También puedes usarlo.

SHASHANK GUPTA
fuente
2

Talos es exactamente lo que estás buscando; Una solución automatizada para buscar combinaciones de hiperparámetros para los modelos Keras. Puede que no sea objetivo ya que soy el autor, pero la intención ha sido proporcionar una alternativa con la curva de aprendizaje más baja posible mientras expongo completamente la funcionalidad de Keras.

Alternativamente, como ya se mencionó, puede buscar en Hyperas , o luego SKlearn o AutoKeras . Que yo sepa, al momento de escribir, estos 4 son las opciones para los usuarios de Keras específicamente.

mikkokotila
fuente