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.
Antworten:
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_shape
Argument 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.
quelle
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.
quelle
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.
quelle
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.
quelle