Wyszukiwanie hiperparametrów dla LSTM-RNN za pomocą Keras (Python)

18

Z samouczka RNN firmy Keras: „RNN są trudne. Wybór wielkości partii jest ważny, wybór straty i optymalizatora ma kluczowe znaczenie itp. Niektóre konfiguracje nie będą zbieżne”.

Jest to więc bardziej ogólne pytanie dotyczące dostrajania hiperparametrów LSTM-RNN w Keras. Chciałbym wiedzieć o podejściu do znalezienia najlepszych parametrów dla Twojego RNN.

Zacząłem od przykładu IMDB na Githubie Keras .

główny model wygląda następująco:

(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 to dobry wynik, a co ważniejsze, oznacza to, że model, choć nie w pełni zoptymalizowany, działa.

Moje dane to Szeregi czasowe, a zadaniem jest przewidywanie binarne, tak samo jak w przykładzie. A teraz mój problem wygląda następująco:

#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

Model jest w zasadzie taki sam jak IMDB. Chociaż wynik oznacza, że ​​niczego się nie uczy. Kiedy jednak używam wanilii MLP-NN, nie mam tego samego problemu, model uczy się, a wynik rośnie. Próbowałem zwiększyć liczbę epok i zwiększyć-zmniejszyć liczbę jednostek LTSM, ale wynik nie wzrośnie.

Chciałbym więc poznać standardowe podejście do dostrajania sieci, ponieważ teoretycznie algorytm powinien działać lepiej niż wielowarstwowa sieć perceptronowa specjalnie dla danych szeregów czasowych.

wacax
źródło
1
Ile masz danych? Jaka jest długość twoich sekwencji? LSTM są naprawdę przydatne tylko w przypadku problemów z dużą ilością danych i długoterminowych zależności.
pir
Wyszukiwanie losowe lub optymalizacja bayesowska to standardowe sposoby znajdowania hiperparametrów :)
pir
1
Czy na pewno potrzebujesz warstwy do osadzania? Wiele zestawów danych szeregów czasowych nie potrzebowałoby tego.
pir
Mam prawie 100 000 punktów danych i dwa razy więcej funkcji niż w przykładzie IMDB, więc nie sądzę, że to jest problem. Jeśli chodzi o warstwę osadzania, w jaki sposób dokładnie połączyć warstwę LSTM z wejściem? Zgodnie z dokumentacją keras.io/layers/recurrent/#lstm LSTM Keras przyjmuje tylko argumenty inicjalizacji, aktywacji i output_dim. Jeśli to jest przyczyną błędu, bardzo doceniony zostanie kod opisujący, jak wyeliminować warstwę osadzania.
wacax
Proszę zobaczyć moją odpowiedź. Wygląda na to, że nie potrzebujesz warstwy do osadzania.
pir

Odpowiedzi:

5

Osadzająca warstwa zamienia dodatnie liczby całkowite (indeksy) w gęste wektory o stałym rozmiarze. Na przykład [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]. Ta konwersja reprezentacji jest uczona automatycznie z warstwą osadzania w Keras (patrz dokumentacja ).

Wydaje się jednak, że dane nie potrzebują takiej warstwy do osadzania, aby przeprowadzić konwersję. Posiadanie niepotrzebnej warstwy osadzania prawdopodobnie uniemożliwi prawidłowe działanie LSTM. W takim przypadku należy po prostu usunąć warstwę osadzania.

W pierwszej warstwie w sieci powinien zostać input_shapedodany argument zawierający informacje o wymiarach danych (patrz przykłady ). Zauważ, że możesz dodać ten argument do dowolnej warstwy - nie będzie on obecny w dokumentacji dla żadnej konkretnej warstwy.


Nawiasem mówiąc, hiperparametry są często dostrajane za pomocą wyszukiwania losowego lub optymalizacji bayesowskiej. Chciałbym użyć RMSProp i skupić się na dostrajaniu wielkości partii (wielkości 32, 64, 128, 256 i 512), obcinaniu gradientu (w przedziale 0,1-10) i rezygnacji (w przedziale 0,1-0,6). Specyfika zależy oczywiście od danych i architektury modelu.

pir
źródło
Czym proponujesz zastąpić warstwę osadzania? Próbowałem po prostu usunąć warstwę osadzania, ale to nie działa.
wacax
1
Spójrz na inne przykłady - zacznij np. Bezpośrednio od warstwy gęstej. Pamiętaj, aby ustawić parametr input_shape.
pir
5

Poleciłbym optymalizację Bayesian do wyszukiwania hiperparametrów i uzyskałem dobre wyniki w Spearmint. https://github.com/HIPS/Spearmint Może być konieczne użycie starszej wersji do celów komercyjnych.

Mutian Zhai
źródło
2

Sugerowałbym użycie hyperopt ( https://github.com/hyperopt/hyperopt ), który wykorzystuje swoistą optymalizację bayesowską do wyszukiwania optymalnych wartości hiperparametrów, biorąc pod uwagę funkcję celu. Jest bardziej intuicyjny w użyciu niż Spearmint.

PS: Istnieje opakowanie hyperopt specjalnie dla keras, hyperas ( https://github.com/maxpumperla/hyperas ). Możesz także z niego korzystać.

SHASHANK GUPTA
źródło
2

Talos jest dokładnie tym, czego szukasz; zautomatyzowane rozwiązanie do wyszukiwania kombinacji hiperparametrów dla modeli Keras. Być może nie jestem obiektywny, ponieważ jestem autorem, ale intencją było zapewnienie alternatywy o możliwie najniższej krzywej uczenia się przy jednoczesnym całkowitym ujawnieniu funkcjonalności Keras.

Alternatywnie, jak już wspomniano, możesz zajrzeć do Hyperas , a następnie SKlearn lub AutoKeras . O ile mi wiadomo, w momencie pisania te 4 opcje są dostępne dla użytkowników Keras.

mikkokotila
źródło