Много к одному и много ко многим примерам LSTM в Керасе

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

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

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

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

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

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 векторы, чтобы приспособить его к соответствующему размеру.

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

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

A) как Vanilla 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')) 
Другие вопросы по тегам