Как использовать опцию return sequences и TimeDistributed layer в 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)". Когда моя модель получает пользовательский ввод, она должна вывести системное действие.
Но я не могу понять!-Вариант -1--> и TimeDistributed
слой после LSTM. К реализовать "многие-ко-многим (2)", return_sequences==True
и добавить TimeDistributed
после LSTMs требуется? Буду признателен, если вы дадите более подробное описание.
return_sequences: Boolean. Возвращать ли последний вывод в выходной последовательности или полную последовательность.
TimeDistributed: эта оболочка позволяет применять слой к каждому временному срезу входного сигнала.
Обновлено 2017/03/13 17: 40
I думаю, я мог бы понять . Но я все еще не уверен TimeDistributed
. Если я добавлю TimeDistributed
после LSTMs модель такая же, как "мой много-ко-многим(2)" ниже? Поэтому я думаю, что плотные слои применяются для каждого выхода.
2 ответов
слой LSTM и распределенная по времени оболочка-это два разных способа получить отношение "многие ко многим", которое вы хотите.
- LSTM будет есть слова вашего предложения один за другим, вы можете выбрать через "return_sequence", чтобы опередить что-то (состояние) на каждом шаге (после каждого обработанного слова) или только вывести что-то после того, как последнее слово было съедено. Таким образом, при return_sequence=TRUE вывод будет последовательностью одинаковой длины, при return_sequence=FALSE, выход будет только один вектор.
- TimeDistributed. Эта обертка позволяет применять один слой (например, плотный) к каждому элементу вашей последовательности самостоятельно. Этот слой будет иметь точно такие же веса для каждого элемента, это то же самое, что будет применяться к каждому слову, и это, конечно, вернет последовательность слов, обрабатываемых независимо.
как вы можете видеть, разница между ними заключается в том, что LSTM "распространяет информация через последовательность, она съест одно слово, обновит свое состояние и вернет его или нет. Затем он продолжит следующее слово, все еще неся информацию из предыдущих.... как и в TimeDistributed, слова будут обрабатываться так же самостоятельно, как если бы они были в бункерах, и один и тот же слой применяется к каждому из них.
поэтому вам не нужно использовать LSTM и TimeDistributed подряд, вы можете делать все, что хотите, просто имейте в виду, что каждый из них делает.
надеюсь, это яснее?
EDIT:
распределенное время в вашем случае применяет плотный слой к каждому элементу, который был выведен LSTM.
рассмотрим пример:
у вас есть последовательность слов n_words, которые встроены в измерения emb_size. Так что ваш вклад-это 2D-тензор формы (n_words, emb_size)
сначала вы применяете LSTM с выходным размером = lstm_output
и return_sequence = True
. На выходе все равно быть squence, так что это будет 2D тензор формы (n_words, lstm_output)
.
Так у вас n_words векторы lstm_output длина.
теперь вы применить TimeDistributed плотный слой с 3 измерения выход параметра плотной. Так Что TimeDistributed(Плотный (3)).
Это будет применяться плотное (3) n_words раз, к каждому вектору размера lstm_output в вашей последовательности независимо... все они станут векторами длины 3. Ваш выход по-прежнему будет последовательностью, поэтому 2D-тензор, формы теперь (n_words, 3)
.
это яснее? :-)
return_sequences=True parameter:
Если мы хотим иметь последовательность для вывода, а не только один вектор, как мы сделали с обычными нейронными сетями, поэтому необходимо установить return_sequences в 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 выход теперь представляет собой трехмерный вектор. Если мы введем это в плотный слой, это вызовет ошибку, потому что плотный слой принимает только двумерный ввод. Чтобы ввести трехмерный вектор, нам нужно использовать слой оболочки, называемый TimeDistributed. Этот слой поможет нам сохранить форму вывода, так что мы сможем достичь последовательности в качестве вывода в конце.