Hyperparametersuche nach LSTM-RNN mit Keras (Python)

18

Vom Keras RNN Tutorial: "RNNs sind knifflig. Die Wahl der Stapelgröße ist wichtig, die Wahl des Verlusts und des Optimierers ist kritisch usw. Einige Konfigurationen konvergieren nicht."

Dies ist also eher eine allgemeine Frage zum Optimieren der Hyperparameter eines LSTM-RNN auf Keras. Ich würde gerne wissen, wie Sie die besten Parameter für Ihr RNN finden können.

Ich habe mit dem IMDB-Beispiel für Keras 'Github begonnen .

Das Hauptmodell sieht so aus:

(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 ist eine faire Punktzahl, und was noch wichtiger ist, dass das Modell funktioniert, auch wenn es nicht vollständig optimiert ist.

Meine Daten sind Zeitreihen und die Aufgabe ist eine binäre Vorhersage, genau wie im Beispiel. Und jetzt sieht mein Problem so aus:

#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

Das Modell ist im Grunde dasselbe wie das IMDB-Modell. Obwohl das Ergebnis bedeutet, dass es nichts lernt. Wenn ich jedoch einen Vanille-MLP-NN verwende, habe ich nicht das gleiche Problem, das Modell lernt und die Punktzahl steigt. Ich habe versucht, die Anzahl der Epochen zu erhöhen und die Anzahl der LTSM-Einheiten zu erhöhen bzw. zu verringern, aber die Punktzahl wird sich nicht erhöhen.

Daher würde ich gerne einen Standardansatz zur Optimierung des Netzwerks kennen, da der Algorithmus theoretisch eine bessere Leistung als ein mehrschichtiges Perceptron-Netzwerk speziell für diese Zeitreihendaten aufweisen sollte.

Wacax
quelle
1
Wie viele Daten haben Sie? Wie lang sind deine Sequenzen? LSTMs eignen sich nur für Probleme mit vielen Daten und langfristigen Abhängigkeiten.
Pir
Zufallssuche oder Bayes'sche Optimierung sind Standardmethoden zum Auffinden von Hyperparametern :)
pir
1
Sind Sie sicher, dass Sie die Einbettungsschicht benötigen? Viele Zeitreihendatensätze würden dies nicht benötigen.
Pir
Ich habe fast 100.000 Datenpunkte und doppelt so viele Funktionen wie das IMDB-Beispiel, daher glaube ich nicht, dass dies das Problem ist. Wie genau würden Sie für die Einbettungsschicht die LSTM-Schicht mit dem Eingang verbinden? Der Dokumentation keras.io/layers/recurrent/#lstm zufolge verwendet Keras 'LSTM nur Initialisierungen, Aktivierungen und output_dim als Argumente. Wenn dies die Fehlerquelle ist, wird der Code, der beschreibt, wie die Einbettungsschicht beseitigt werden kann, sehr geschätzt.
Wacax
Bitte sehen Sie meine Antwort. Anscheinend brauchen Sie die Einbettungsschicht nicht.
Pir

Antworten:

5

Eine Einbettungsebene wandelt positive Ganzzahlen (Indizes) in dichte Vektoren fester Größe um. Zum Beispiel [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]. Diese Repräsentationskonvertierung wird automatisch mit der Einbettungsebene in Keras gelernt (siehe Dokumentation ).

Es scheint jedoch, dass Ihre Daten keine solche Einbettungsschicht benötigen, um eine Konvertierung durchzuführen. Eine unnötige Einbettungsschicht ist wahrscheinlich der Grund dafür, dass Sie Ihren LSTM nicht ordnungsgemäß zum Laufen bringen können. Wenn dies der Fall ist, sollten Sie einfach die Einbettungsschicht entfernen.

Der ersten Ebene in Ihrem Netzwerk sollte dann das input_shapeArgument mit Informationen zu den Abmessungen Ihrer Daten hinzugefügt werden (siehe Beispiele ). Beachten Sie, dass Sie dieses Argument zu jeder Ebene hinzufügen können - es ist in der Dokumentation für keine bestimmte Ebene vorhanden.


Übrigens werden Hyperparameter häufig durch Zufallssuche oder Bayes'sche Optimierung eingestellt. Ich würde RMSProp verwenden und mich auf die Optimierung der Stapelgröße (Größen wie 32, 64, 128, 256 und 512), Gradientenbeschneidung (im Intervall 0,1-10) und Dropout (im Intervall 0,1-0,6) konzentrieren. Die Einzelheiten hängen natürlich von Ihren Daten und Ihrer Modellarchitektur ab.

pir
quelle
Was schlagen Sie vor, um die Einbettungsschicht durch zu ersetzen? Ich habe versucht, einfach die Einbettungsebene zu entfernen, aber das funktioniert nicht.
Wacax
1
Schauen Sie sich die anderen Beispiele an - beginnen Sie zB direkt mit der Dichten Ebene. Denken Sie daran, den Parameter input_shape festzulegen.
Pir
5

Ich würde Bayesian Optimization für die Hyperparametersuche empfehlen und mit Spearmint gute Ergebnisse erzielen. https://github.com/HIPS/Spearmint Für die kommerzielle Nutzung müssen Sie möglicherweise eine ältere Version verwenden.

Mutian Zhai
quelle
2

Ich würde vorschlagen, hyperopt ( https://github.com/hyperopt/hyperopt ) zu verwenden, das eine Art Bayes'sche Optimierung für die Suche nach optimalen Werten von Hyperparametern verwendet, wenn die Zielfunktion gegeben ist. Es ist intuitiver zu bedienen als Spearmint.

PS: Es gibt einen Wrapper von Hyperopt, speziell für Keras, Hyperas ( https://github.com/maxpumperla/hyperas ). Sie können es auch verwenden.

SHASHANK GUPTA
quelle
2

Talos ist genau das, wonach Sie suchen. eine automatisierte Lösung für die Suche nach Hyperparameterkombinationen für Keras-Modelle. Ich bin vielleicht nicht objektiv, da ich der Autor bin, aber die Absicht war, eine Alternative mit der geringstmöglichen Lernkurve bereitzustellen und gleichzeitig die Keras-Funktionalität vollständig zu offenbaren.

Alternativ können Sie, wie bereits erwähnt, in Hyperas oder dann in SKlearn oder AutoKeras suchen . Meines Wissens zum Zeitpunkt des Schreibens sind diese 4 Optionen speziell für Keras-Benutzer.

mikkokotila
quelle