Wiele do jednego i wiele do wielu przykładów LSTM w Keras

Staram się zrozumieć LSTM i jak je budować z Keras. Okazało się, że są głównie 4 tryby do uruchomienia RNN (4 właściwe Na zdjęciu)

Tutaj wpisz opis obrazka Źródło obrazu: Andrej Karpathy

Teraz zastanawiam się, jak wyglądałby minimalistyczny fragment kodu dla każdego z nich w Keras. Więc coś w stylu

model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))

Dla każdego z 4 zadań, może z odrobiną wyjaśnienia.

Author: Tautvydas, 2017-03-26

2 answers

Więc:

  1. Jeden do jednego : możesz użyć warstwy Dense, ponieważ nie przetwarzasz sekwencji:

    model.add(Dense(output_size, input_shape=input_shape))
    
  2. Jeden do wielu: ta opcja nie jest dobrze obsługiwana, ponieważ łączenie modeli nie jest bardzo łatwe w Keras, więc następująca wersja jest najłatwiejsza:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
    
  3. Wiele do jednego: właściwie, Twój fragment kodu jest (prawie) przykładem takiego podejścia:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
    
  4. Many-to-many: to jest najprostszym fragmentem, gdy długość wejścia i wyjścia odpowiada liczbie powtarzających się kroków:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    
  5. Wiele do wielu, gdy liczba kroków różni się od długości wejścia/wyjścia: jest to dziwne w Keras. Nie ma łatwych fragmentów kodu, aby to zakodować.

EDIT: Ad 5

W jednej z moich ostatnich aplikacji zaimplementowaliśmy coś, co może być podobne do many-to-many z czwartego obrazu. In case you want aby mieć sieć o następującej architekturze (gdy wejście jest dłuższe niż wyjście):

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | | | | 
                                  O O O O O O
Można to osiągnąć w następujący sposób:]}
model = Sequential()
model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
model.add(Lambda(lambda x: x[:, -N:, :])) #Select last N from output

Gdzie N jest liczbą ostatnich kroków, które chcesz wykonać(na obrazku N = 3).

Od tego momentu aż do:

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | 
                                  O O O 

Jest tak prosty jak sztuczny ciąg o długości N za pomocą np. z 0 wektorów, aby dostosować go do odpowiedniej wielkości.

 138
Author: Marcin Możejko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-09 06:17:27

Świetna odpowiedź @Marcin Możejko

Dodałbym do Nr. 5 (wiele do wielu o różnej długości wejścia/Wyjścia):

A) jako Vanilla LSTM

model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))

B) jako enkoder-Dekoder LSTM

model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES))  
model.add(RepeatVector(N_OUTPUTS))
model.add(LSTM(N_BLOCKS, return_sequences=True))  
model.add(TimeDistributed(Dense(1)))
model.add(Activation('linear')) 
 10
Author: gustavz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-09 13:23:23