Подтвердить что ты не робот

От многих до одного и от многих до многих примеров LSTM в Keras

Я пытаюсь понять LSTM и как их построить с помощью Keras. Я обнаружил, что в основном есть 4 режима для запуска RNN (4 правильных на рисунке)

enter image description here Источник изображения: Андрей Карпати

Теперь мне интересно, как будет выглядеть минималистичный фрагмент кода для каждого из них в Keras. Так что-то вроде

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

для каждого из 4 заданий, возможно, с небольшим объяснением.

4b9b3361

Ответ 1

Так:

  1. Один-к-одному: вы можете использовать Dense слой, поскольку вы не обрабатываете последовательности:
    model.add(Dense(output_size, input_shape=input_shape))

2. Один-ко-многим: эта опция не поддерживается, так как цепочка моделей не очень проста в Keras, поэтому следующая версия является самой простой:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
  1. Много-к-одному: на самом деле, ваш фрагмент кода (почти) является примером такого подхода:
    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
  1. Многие ко многим: это самый простой фрагмент кода, когда длина входных и выходных данных соответствует числу повторяющихся шагов:
    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
  1. Много ко многим, когда количество шагов отличается от длины ввода/вывода: в Керасе это очень сложно. Там нет простых фрагментов кода, чтобы закодировать это.

РЕДАКТИРОВАТЬ: объявление 5

В одном из моих недавних приложений мы реализовали что-то похожее на многие-многие из 4-го изображения. Если вы хотите иметь сеть со следующей архитектурой (когда вход длиннее, чем выход):

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

Вы можете достичь этого следующим образом:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    model.add(Lambda(lambda x: x[:, -N:, :]

Где N - количество последних шагов, которые вы хотите пройти (на рисунке N = 3).

С этого момента добираемся до:

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

это так же просто, как искусственная последовательность заполнения длины N с использованием, например, 0 векторов, чтобы отрегулировать ее до подходящего размера.

Ответ 2

Отличный ответ @Marcin Możejko

Я бы добавил следующее к NR.5 (многие ко многим с различной длиной входа/выхода):

А) как ванильный LSTM

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

Б) в качестве кодера-декодера 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'))