Как использовать параметр return_sequences и слой TimeDistributed в Keras?

У меня есть диалоговый корпус, как показано ниже. И я хочу реализовать модель LSTM, которая предсказывает системное действие. Системные действия, описанные как бит-вектор. И пользовательские входы вычисляются как слово-вложение, которое также является битовым вектором.

t1: user: "Do you know an apple?", system: "no"(action=2)
t2: user: "xxxxxx", system: "yyyy" (action=0)
t3: user: "aaaaaa", system: "bbbb" (action=5)

Итак, что я хочу понять, это "много для многих (2)" моделей. Когда моя модель получает пользовательский ввод, она должна выводить системное действие. введите описание изображения здесь Но после LSTM я не могу понять параметр return_sequences и слой TimeDistributed. Чтобы реализовать "много-ко-многим (2)", return_sequences == True и добавление TimeDistributed после LSTM требуются? Я ценю, если вы дадите им больше описания.

return_sequences: Boolean. Возвращать ли последний выход в выходной последовательности или полную последовательность.

TimeDistributed. Эта оболочка позволяет применить слой к каждому временному фрагменту ввода.

Обновлено 2017/03/13 17:40

Я думаю, я мог бы понять вариант return_sequence. Но я еще не уверен в TimeDistributed. Если я добавлю TimeDistributed после LSTM, модель будет такой же, как "мои многие-ко-многим (2)" ниже? Поэтому я думаю, что для каждого выхода применяются плотные слои. введите описание изображения здесь

Ответы

Ответ 1

Уровень LSTM и обертка TimeDistributed - это два разных способа получить отношения "многие ко многим", которые вы хотите.

  • LSTM будет употреблять слова вашего предложения по одному, вы можете выбрать через "return_sequence", чтобы вывести что-то (состояние) на каждом шаге (после каждого обрабатываемого слова) или вывести только что-то после того, как последнее слово было съедено. Таким образом, с return_sequence = TRUE вывод будет последовательностью той же длины, с return_sequence = FALSE, выход будет всего одним вектором.
  • TimeDistributed. Эта оболочка позволяет применить один слой (например, Dense, например) к каждому элементу вашей последовательности независимо. Этот слой будет иметь одинаковые веса для каждого элемента, то же самое будет применяться к каждому слову, и он, конечно же, вернет последовательность слов, обрабатываемых независимо.

Как вы можете видеть, разница между ними заключается в том, что LSTM "распространяет информацию через последовательность, она будет есть одно слово, обновлять свое состояние и возвращать его или нет. Затем оно будет продолжаться со следующим словом, все еще сохраняя информацию из предыдущих..., как и в TimeDistributed, слова будут обрабатываться одинаково сами по себе, как если бы они находились в силосах, и один и тот же слой относится к каждому из них.

Поэтому вам не нужно использовать LSTM и TimeDistributed в строке, вы можете делать все, что хотите, просто имейте в виду, что делают каждый из них.

Надеюсь, это яснее?

EDIT:

Время, распределенное в вашем случае, применяет плотный слой к каждому элементу, который был выведен LSTM.

Возьмем пример:

У вас есть последовательность слов n_words, которые встроены в размеры emb_size. Таким образом, ваш вход представляет собой 2D-тензор формы (n_words, emb_size)

Сначала вы применяете LSTM с выходным размером = lstm_output и return_sequence = True. Выход по-прежнему будет сквален, поэтому он будет двумерным тензором формы (n_words, lstm_output). Итак, у вас есть векторы n_words длины lstm_output.

Теперь вы применяете плотный слой TimeDistributed, используя, например, 3 измерения, как параметр Dense. Итак, TimeDistributed (Плотный (3)). Это применит Dense (3) n_words раз, к каждому вектору размера lstm_output в вашей последовательности независимо... все они станут векторами длины 3. Ваш результат по-прежнему будет последовательностью, так что 2D-тензор, теперь форма (n_words, 3),

Яснее?: -)

Ответ 2

    return_sequences=True parameter:

Если мы хотим иметь последовательность для вывода, а не только один вектор, как это было в случае с нормальными нейронными сетями, поэтому необходимо установить для возвращаемых последовательностей значение True. Конкретно, скажем, у нас есть вход с формой (num_seq, seq_len, num_feature). Если мы не установим return_sequences = True, наш вывод будет иметь форму (num_seq, num_feature), но если мы это сделаем, мы получим результат с формой (num_seq, seq_len, num_feature).

    TimeDistributed wrapper layer:

Так как мы устанавливаем return_sequences = True в слоях LSTM, выход теперь представляет собой трехмерный вектор. Если мы введем это в слой Dense, это вызовет ошибку, потому что слой Dense принимает только двумерный вход. Чтобы ввести трехмерный вектор, нам нужно использовать слой-оболочку, называемый TimeDistributed. Этот слой поможет нам поддерживать форму выходов, так что мы можем достичь последовательности как результат в конце.