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.
Respuestas:
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_shape
argumento 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.
fuente
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.
fuente
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.
fuente
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.
fuente