czytałem trochę o LSTM i ich zastosowaniu do szeregów czasowych i było to interesujące, ale jednocześnie trudne. Jedną rzeczą, z którą miałem trudności ze zrozumieniem, jest podejście do dodawania dodatkowych funkcji do już istniejącej listy funkcji szeregów czasowych. Zakładając, że masz zestaw danych w następujący sposób:
t-3, t-2, t-1, Wyjście
Powiedzmy teraz, że wiesz, że masz funkcję, która wpływa na wynik, ale niekoniecznie jest to funkcja szeregów czasowych, powiedzmy, że jest to pogoda na zewnątrz. Czy to coś, co możesz po prostu dodać, a LSTM będzie w stanie rozróżnić, co jest aspektem szeregów czasowych, a co nie?
Odpowiedzi:
W przypadku RNN (np. LSTM i GRU) wejście warstwy jest listą kroków czasowych, a każdy krok czasowy jest tensorem cech. Oznacza to, że możesz mieć tensor wejściowy taki jak ten (w notacji Python):
Zatem absolutnie możesz mieć wiele funkcji za każdym razem. Moim zdaniem pogoda jest funkcją szeregów czasowych: tam, gdzie mieszkam, zdarza się, że jest funkcją czasu. W związku z tym rozsądne byłoby zakodowanie informacji o pogodzie jako jednej z funkcji w każdym czasie (z odpowiednim kodowaniem, np. Pochmurno = 0, słonecznie = 1 itd.).
Jeśli masz dane niepowiązane z szeregami czasowymi, przekazanie ich przez LSTM nie ma sensu. Być może LSTM i tak zadziała, ale nawet jeśli tak, prawdopodobnie będzie kosztować wyższą stratę / niższą dokładność na czas szkolenia.
Alternatywnie możesz wprowadzić tego rodzaju „dodatkowe” informacje do swojego modelu poza LSTM za pomocą dodatkowych warstw. Możesz mieć przepływ danych taki jak ten:
Więc połączysz swoje wejścia pomocnicze z wyjściami LSTM i kontynuujesz stamtąd swoją sieć. Teraz twój model jest po prostu wieloma wejściami.
Załóżmy na przykład, że w konkretnej aplikacji zachowane jest tylko ostatnie wyjście sekwencji wyjściowej LSTM. Powiedzmy, że jest to wektor długości 10. Dodatkowym wejściem może być zakodowana pogoda (czyli skalar). Twoja warstwa scalania może po prostu dołączyć pomocnicze informacje pogodowe na końcu wektora wyjściowego LSTM, aby utworzyć pojedynczy wektor o długości 11. Ale nie musisz po prostu zachowywać ostatniego timestepu wyjściowego LSTM: jeśli LSTM wygenerował 100 timepeps, każdy z 10-wektorowymi funkcjami możesz nadal korzystać z pomocniczych informacji o pogodzie, co daje 100 kroków czasowych, z których każdy składa się z wektora 11 punktów danych.
Dokumentacja Keras na temat jego funkcjonalnego API ma dobry przegląd tego.
W innych przypadkach, jak wskazuje @horaceT, możesz chcieć uzależnić LSTM od danych innych niż czasowe. Na przykład prognozuj jutro pogodę, podając lokalizację. W tym przypadku oto trzy sugestie, każda z pozytywnymi / negatywnymi:
Niech pierwszy pomiar czasu będzie zawierał twoje dane warunkowe, ponieważ skutecznie „ustawi” ono stan wewnętrzny / ukryty twojego RNN. Szczerze mówiąc, nie zrobiłbym tego z wielu powodów: twoje dane warunkowe muszą mieć taki sam kształt, jak reszta twoich funkcji, utrudnia tworzenie stanowych numerów RNN (jeśli chodzi o to, aby bardzo uważnie śledzić sposób, w jaki podajesz dane do sieci), sieć może „zapomnieć” dane warunkowe z wystarczającą ilością czasu (np. długie sekwencje treningowe lub długie sekwencje predykcyjne) itp.
Uwzględnij dane jako część danych czasowych. Zatem każdy wektor cech w określonym czasie zawiera dane „głównie” szeregów czasowych, ale następnie dołącza dane warunkowe na końcu każdego wektora cech. Czy sieć nauczy się to rozpoznawać? Prawdopodobnie, ale nawet wtedy tworzysz trudniejsze zadanie uczenia się, zanieczyszczając dane sekwencji informacjami niesekwencyjnymi. Więc ja też zniechęcać tego.
Prawdopodobnie najlepszym rozwiązaniem byłoby bezpośrednie oddziaływanie na ukryty stan RNN w czasie zero. Takie podejście przyjęli Karpathy i Fei-Fei oraz Vinyals i in . Tak to działa:
Podejście to jest najbardziej „teoretycznie” poprawne, ponieważ odpowiednio uwarunkowuje RNN na wejściach innych niż czasowe, naturalnie rozwiązuje problem kształtu, a także pozwala uniknąć zanieczyszczenia punktów czasowych danych wejściowych dodatkowymi, nieczasowymi informacjami. Minusem jest to, że takie podejście często wymaga kontroli architektury na poziomie grafu, więc jeśli używasz abstrakcji wyższego poziomu, takiej jak Keras, trudno będzie ją wdrożyć, chyba że dodasz własny typ warstwy.
źródło
Opierając się na wszystkich dobrych odpowiedziach tego wątku, napisałem bibliotekę do warunku na wejściach pomocniczych. Abstrahuje ona od całej złożoności i została zaprojektowana tak, aby była jak najbardziej przyjazna dla użytkownika:
https://github.com/philipperemy/cond_rnn/ (tensorflow)
Mam nadzieję, że to pomoże!
źródło
W keras LSTM jest funkcja
reset_states(states)
.Jednak stanami parametrów jest powiązanie dwóch stanów, stanu ukrytego hi stanu komórki.
byłoby interesujące wiedzieć, czy powinieneś zainicjować
h
lubc
zgodnie z podejściem w wyżej wymienionych artykułach.źródło
Prawdopodobnie nie jest to najbardziej efektywny sposób, ale zmienne statyczne można powtarzać do długości szeregów czasowych przy użyciu
tf.tile()
.źródło