Как я могу установить плотное узкое место в сложенном LSTM с Keras? - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть:

        self.model.add(Bidirectional(LSTM(lstm1_size, input_shape=(
            seq_length, feature_dim), return_sequences=True)))
        self.model.add(BatchNormalization())
        self.model.add(Dropout(0.2))

        self.model.add(Bidirectional(
            LSTM(lstm2_size, return_sequences=True)))
        self.model.add(BatchNormalization())
        self.model.add(Dropout(0.2))

        # BOTTLENECK HERE

        self.model.add(Bidirectional(
            LSTM(lstm3_size, return_sequences=True)))
        self.model.add(BatchNormalization())
        self.model.add(Dropout(0.2))

        self.model.add(Bidirectional(
            LSTM(lstm4_size, return_sequences=True)))
        self.model.add(BatchNormalization())
        self.model.add(Dropout(0.2))

        self.model.add(Dense(feature_dim, activation='linear'))

Однако я хочу настроить autoencoder -подобную настройку без необходимости иметь 2 отдельные модели. Там, где у меня есть комментарий BOTTLENECK HERE, я хочу иметь вектор некоторого измерения, скажем, bottleneck_dim.

. После этого должны быть некоторые слои LSTM, которые затем восстанавливают последовательность того же размера, что и начальный вход. Однако я считаю, что добавление слоя Dense не вернет один вектор, а вместо этого вернет векторы для каждой длины последовательности?

1 Ответ

1 голос
/ 25 февраля 2020
  • Dense был обновлен, чтобы автоматически действовать, как если бы он был обернут в TimeDistributed - т.е. вы получите (batch_size, seq_length, lstm2_size).
  • Обходной путь должен поместить Flatten() перед ним, поэтому форма вывода Dense будет (batch_size, seq_length * lstm2_size). Однако я не рекомендовал бы это, поскольку это может повредить временную информацию (вы смешиваете каналы и временные шаги). Кроме того, он ограничивает сеть до seq_length, поэтому вы больше не можете проводить обучение или вывод на любом другом seq_length.

Предпочтительной альтернативой является Bidirectional(LSTM(..., return_sequences=False)), которая возвращает только последний временной шаг выходной, в форме (batch_size, lstm_bottleneck_size). Чтобы передать его выходные данные следующему LSTM, вам понадобится RepeatVector(seq_length) после слоя =False.

Однако помните о «узком месте»; например, если (seq_length, feature_dim) = (200, 64) и lstm_bottleneck_size = 400, это сокращение (1 * 400) / (200 * 64) = x32 , которое является довольно большим и может привести к перегрузке сети. Я бы предложил с х8 в качестве цели.

...