Сомнения относительно «Понимания Keras LSTM» - PullRequest
0 голосов
/ 28 декабря 2018

Я новичок в LSTM и прохожу через Понимание LSTM Keras , и у меня возникли некоторые глупые сомнения, связанные с красивым ответом Daniel Moller .

Вот некоторые из моих сомнений:

  1. В разделе Achieving one to many указано, что мы можем использовать stateful=True для повторного получениявывод одного шага и служит его входом следующего шага (требуется output_features == input_features).

    На диаграмме One to many with repeat vector повторный вектор подается в качестве входных данных на всем временном шаге, тогда какв One to many with stateful=True выход подается как вход на следующем шаге по времени.Итак, разве мы не меняем способ работы слоев, используя stateful=True?

    Какой из двух вышеуказанных подходов (с использованием вектора повторения ИЛИ подачи предыдущего временного шага в качестве следующего входа) долженпри построении RNN ?

  2. в разделе One to many with stateful=True измените поведение one to many в коде для ручного цикла для прогнозирования,как мы узнаем переменную steps_to_predict, потому что заранее не знаем длину выходной последовательности.

    Я также не понял, как вся модель использует last_step output для генерации next_step ouput,Это смутило меня по поводу работы функции model.predict().Я имею в виду, не model.predict() одновременно предсказывает одновременно целые выходные последовательности, вместо того, чтобы циклически генерировать no. of output sequences (значение которого я до сих пор не знаю) и делать model.predict() для прогнозирования определенного временного шагавывод в данной итерации?

  3. Я не мог понять весь случай Many to many.Любая другая ссылка будет полезна.

  4. Я понимаю, что мы используем model.reset_states(), чтобы убедиться, что новая партия не зависит от предыдущей партии.Но, мы вручную создаем партии последовательности таким образом, чтобы одна партия следовала за другой партией, или Keras в режиме stateful=True автоматически делит последовательность на такие партии.

    Если это сделано вручную, тогда зачем кому-то делить набор данных на такие партии, в которых часть последовательности находится в одной партии, а другая - в следующей?

  5. Наконец, каковы практические реализации или примеры / варианты использования, где stateful=True будет использоваться (потому что это кажется чем-то необычным)?Я изучаю LSTM, и я впервые знакомлюсь с stateful в Керасе.

Может ли кто-нибудь помочь мне объяснить мои глупые вопросы, чтобы мне было понятноРеализация LSTM в Keras?

РЕДАКТИРОВАТЬ: запрашивать некоторые из них для уточнения текущего ответа, а некоторые для оставшихся сомнений

A .Итак, в основном с состоянием позволяет нам keep OR reset внутреннее состояние после каждой партии.Тогда как модель узнает, если мы продолжаем сбрасывать внутреннее состояние снова и снова после каждой тренировки?Действительно ли сброс означает сброс параметров (используемых для вычисления скрытого состояния)?

B .В строке If stateful=False: automatically resets inner state, resets last output step.Что вы имели в виду, сбросив последний шаг вывода?Я имею в виду, что если каждый временной шаг производит свой собственный выход, то что означает сброс последнего выходного шага и это тоже только последний?

C .В ответ на Question 2 и 2-ю точку Question 4 я все еще не получил ваш manipulate the batches between each iteration и необходимость stateful ((последняя строка Question 2), которая только сбрасывает состояния).Я дошел до того, что мы не знаем входные данные для каждого выходного сигнала, генерируемого за временной шаг.

Итак, вы разбиваете последовательности на последовательности only one-step и затем используете new_step = model.predict(last_step), но тогда как вы узнаете, как долго вам нужно делать это снова и снова (должна быть точка остановки дляпетля)?Также объясните часть stateful (в последней строке Question 2).

D .В коде под One to many with stateful=True кажется, что цикл for (ручной цикл) используется для предсказания следующего слова, используемого только во время теста.Включает ли модель эту вещь сама во время поезда, или нам manually нужно использовать эту петлю также во время поезда?

E .Предположим, что мы выполняем некоторую работу машинного перевода , я думаю, что разрыв последовательностей произойдет после того, как весь ввод (язык для перевода) будет введен во временные шаги ввода, а затем будет генерироваться вывод (переведенный язык)на каждом временном шаге будет происходить через manual loop, потому что теперь мы получили входные данные и начали выводить на каждом временном шаге, используя итерацию.Я правильно понял?

F .Так как для работы по умолчанию LSTM требуется 3 вещи, упомянутые в ответе, поэтому в случае разрыва последовательностей current_input и previous_output питаются одинаковыми векторами, потому что их значение в случае отсутствия входного тока одинаково?

G .В разделе многие ко многим с сохранением состояния = True в разделе Predicting: код выглядит так:

predicted = model.predict(totalSequences)
firstNewStep = predicted[:,-1:]

С тех пор, как ручной цикл finding the very next word in the current sequence имеетдо сих пор не использовался, откуда я знаю count временных шагов, которые были предсказаны model.predict(totalSequences), так что последний шаг из предсказанных (predicted[:,-1:]) будет позже использоваться для генерацииостальные последовательности?Я имею в виду, как мне узнать количество последовательностей, которые были созданы в predicted = model.predict(totalSequences) до manual for loop (позже использовалось).

РЕДАКТИРОВАТЬ 2:

I .В ответе D я так и не получил, как я буду тренировать свою модель?Я понимаю, что использование ручного цикла (во время обучения) может быть довольно болезненным, но тогда, если я не буду его использовать, как модель будет обучаться в обстоятельствах, когда we want the 10 future steps, we cannot output them at once because we don't have the necessary 10 input steps?Будет ли просто использование model.fit() решить мою проблему?

II .D последний пункт ответа, You could train step by step using train_on_batch only in the case you have the expected outputs of each step. But otherwise I think it's very complicated or impossible to train..

Можете ли вы объяснить это более подробно?

Что означает step by step?Если у меня нет ИЛИ есть выход для более поздних последовательностей, как это повлияет на мое обучение?Нужно ли мне еще ручной цикл во время тренировки.Если нет, то будет ли функция model.fit() работать должным образом?

III .Я интерпретировал "repeat" option как repeat vector.Разве использование вектора повторения было бы просто хорошо для случая one to many и не подходит для случая many to many, поскольку последний будет иметь много входных векторов на выбор (которые будут использоваться в качестве одного повторного вектора)?Как вы будете использовать repeat vector для дела many to many?

1 Ответ

0 голосов
/ 15 января 2019

Вопрос 3

Понимание вопроса 3 является своего рода ключом к пониманию других, поэтому давайте попробуем сначала.

Все повторяющиеся слои в Keras выполняют скрытые петли.Эти циклы совершенно невидимы для нас, но мы можем видеть результаты каждой итерации в конце .

Количество невидимых итераций равно измерению time_steps.Таким образом, текущие вычисления LSTM происходят относительно шагов.

Если мы передадим ввод с X шагами, будет X невидимых итераций.

Каждая итерация в LSTM будет принимать 3 входа:

  • Соответствующий срез входных данных для этого шага
  • Внутреннее состояние слоя
  • Вывод последней итерации

Итак, возьмем следующий пример изображения, где наш ввод состоит из 5 шагов:

many to many

Что будетКерас делать в одном прогнозе?

  • Шаг 0:
    • Сделайте первый шаг ввода, input_data[:,0,:] срез в форме (batch, 2)
    • Примите внутреннее состояние (которое равно нулю)на этом этапе)
    • Выполнить последний шаг вывода (который не существует для первого шага)
    • Выполнить вычисления:
      • Обновить внутреннее состояние
      • Создать один шаг вывода (выход 0)
  • Шаг 1:
    • Выполнить следующий шаг ввода: input_data[:,1,:]
    • Возьмите обновленное внутреннее состояние
    • Возьмите выходные данные, сгенерированные на последнем шаге (вывод 0)
    • Выполните те же вычисления до:
      • Обновитеснова внутреннее состояние
      • Создание еще одного шага вывода (вывод 1)
  • Шаг 2:
    • Take input_data[:,2,:]
    • Возьмите обновленное внутреннее состояние
    • Возьмите вывод 1
    • Пройдите через:
      • Обновите внутреннее состояние
      • Создайте вывод 2
  • И так до шага 4.

  • Наконец:

    • Если stateful=False: автоматически сбрасывает внутреннее состояние, сбрасывает последний выводstep
    • Если stateful=True: сохранить внутреннее состояние, сохранить последний выход, шаг

Вы не увидите ни одного из этих шагов.Это будет выглядеть как один проход.

Но вы можете выбрать между:

  • return_sequences = True: возвращается каждый шаг вывода, форма (batch, steps, units)
    • Это точномного ко многим.Вы получите то же количество шагов в выходных данных, что и во входных данных
  • return_sequences = False: возвращается только последний выходной шаг, форма (batch, units)
    • Это много к одному.Вы генерируете один результат для всей входной последовательности.

Теперь, это ответит на вторую часть вашего вопроса 2: Да, predict вычислит все без вашего ведома.Но:

Количество шагов вывода будет равно количеству шагов ввода

Вопрос 4

Теперь, прежде чем перейти к вопросу 2, давайте посмотрим на 4, который на самом деле является основой ответа.

Да, пакетное деление должно быть выполнено вручную .Керас не изменит ваши партии.Итак, почему я хочу разделить последовательность?

  • 1, последовательность слишком велика, одна партия не умещается в памяти компьютера или графического процессора
  • 2, вы хотите сделать то, что происходит на вопрос 2: манипулировать пакетами между каждым шагом итерации.

Вопрос 2

В вопросе 2 мы «предсказываем будущее».Итак, каково количество шагов вывода?Ну, это число, которое вы хотите предсказать.Предположим, вы пытаетесь предсказать количество клиентов, которые у вас будут на основе прошлого.Вы можете сделать прогноз на один месяц в будущем или на 10 месяцев.Ваш выбор.

Теперь вы правы, полагая, что predict рассчитает всю вещь одновременно, но помните вопрос 3 выше, где я сказал:

Числочисло шагов вывода равно числу шагов ввода

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

Но мы хотим будущего, а не того, что соответствует предыдущим шагам один за другим.Мы хотим, чтобы шаг результата следовал за «последним» шагом.

Итак, мы сталкиваемся с ограничением: как определить фиксированное количество шагов вывода, если у нас нет соответствующих входов?(Входные данные для отдаленного будущего также являются будущим, поэтому они не существуют)

Вот почему мы разбиваем нашу последовательность на последовательности только один шаг .Таким образом, predict также выведет только один шаг .

Когда мы делаем это, у нас есть возможность манипулировать пакетами между каждой итерацией.И у нас есть возможность принимать выходные данные (которых у нас не было раньше) в качестве входных данных.

И отслеживание состояния необходимо, потому что мы хотим, чтобы каждый из этих шагов был соединен как одна последовательность (не отбрасывайте состояния).

Вопрос 5

Лучшее практическое применение stateful=True, которое я знаю, - это ответ на вопрос 2 .Мы хотим манипулировать данными между этапами.

Это может быть фиктивный пример, но другое приложение, если вы, например, получаете данные от пользователя в Интернете.Каждый день, когда пользователь использует ваш веб-сайт, вы даете еще один шаг данных вашей модели (и вы хотите продолжить предыдущую историю этого пользователя в той же последовательности).

Вопрос 1

Затем, наконец, вопрос 1.

Я бы сказал: всегда избегайте stateful=True, если вам это не нужно .
Вам не нужно создавать сеть один-ко-многим, поэтому лучше не используйте ее.

Обратите внимание, что пример stateful=True для этого аналогичен примеру прогнозирования будущего , но вы начинаете с одного шага.Это трудно реализовать, скорость будет хуже из-за ручных циклов.Но вы можете контролировать количество шагов вывода, и в некоторых случаях это может быть чем-то, что вам нужно.

В вычислениях тоже будет разница.И в этом случае я действительно не могу ответить, если один лучше, чем другой.Но я не верю, что будет большая разница.Но сети - это своего рода «искусство», и тестирование может принести забавные сюрпризы.

Ответы на EDIT:

A

Мы не должны путать «состояния» с «весами».Это две разные переменные.

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

Представьте, что вы смотрите фильм (последовательность).Каждая секунда заставляет вас создавать воспоминания, такие как имена персонажей, что они делали, каковы их отношения

Теперь представьте, что вы получаете фильм, который вы никогда не видели, и начинаете смотреть последнюю секунду фильма.Вы не поймете конец фильма, потому что вам нужна предыдущая история этого фильма.(Штаты)

Теперь изображение, которое вы закончили смотреть весь фильм.Теперь вы начнете смотреть новый фильм (новую последовательность).Вам не нужно помнить, что произошло в последнем фильме, который вы видели.Если вы попытаетесь «присоединиться к фильмам», вы запутаетесь.

В этом примере:

  • Веса: ваша способность понимать и понимать фильмы, способность запоминать важные имена и действия
  • Состояния: в приостановленном фильме состояния - это память того, что происходило с самого начала и до наших дней.

Итак, состояния "не изучены".Состояния «вычисляются», строятся шаг за шагом относительно каждой отдельной последовательности в пакете.Вот почему:

  • сброс состояний означает запуск новых последовательностей с шага 0 (начало нового фильма)
  • сохранение состояний означает продолжение тех же последовательностей с последнего шага (продолжение фильма, который былпауза или просмотр части 2 этой истории)

Состояния - это именно то, что заставляет повторяющиеся сети работать так, как если бы они имели «память о прошлых шагах».

B

В LSTM последний шаг вывода является частью "состояний".

Состояние LSTM содержит:

  • матрица памяти, обновляемая каждый шаг вычислениями
  • выходные данные последнего шага

Итак, да: каждый шаг производит свой собственный вывод, но каждый шаг использует вывод последнего шага в качестве состояния.Вот как строится LSTM.

  • Если вы хотите «продолжить» ту же последовательность, вам нужна память о результатах последнего шага
  • Если вы хотите «запустить» новую последовательность, вы не хотитепамять результатов последнего шага (эти результаты будут сохранены, если вы не сбросите состояния)

C

Вы останавливаетесь, когда хотите.Сколько шагов в будущем вы хотите предсказать?Это ваша остановка.

Представьте, что у меня есть последовательность из 20 шагов.И я хочу предсказать 10 шагов в будущем.

В стандартной (не содержащей состояния) сети мы можем использовать:

  • вводить 19 шагов одновременно (от 0 до 18)
  • выводить 19 шагов одновременно(от 1 до 19)

Это «предсказание следующего шага» (обратите внимание на сдвиг = 1 шаг).Мы можем сделать это, потому что у нас есть все входные данные.

Но когда нам нужны 10 будущих шагов, мы не можем вывести их сразу, потому что у нас нет необходимых 10 шагов ввода (эти шаги ввода являются будущими, нам нужна модель, чтобы сначала их прогнозировать).

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

Но я хочу, чтобы все эти шаги были связаны.Если я использую stateful=False, модель увидит много «последовательностей длины 1».Нет, мы хотим одну последовательность длиной 30.

D

Это очень хороший вопрос, и вы меня поймали ...

Состоянием для многих былИдея у меня была при написании этого ответа, но я никогда не использовал это.Я предпочитаю вариант «повторить».

Вы можете тренироваться шаг за шагом, используя train_on_batch, только если у вас есть ожидаемые результаты каждого шага.Но в остальном я думаю, что это очень сложно или невозможно тренироваться.

E

Это один общий подход.

  • Создать сжатый вектор с сетью (этот вектор может быть результатом или сгенерированными состояниями, или обоими вещами)
  • Использовать этот сжатый вектор как начальный вход / состояние другогосети, генерируйте шаг за шагом вручную и останавливайте, когда модель или слово «конец предложения» производятся моделью.

Существуют также модели фиксированного размера без ручной петли.Вы предполагаете, что ваше предложение имеет максимальную длину X слов.Результирующие предложения, которые короче этого, дополняются словами / символами «конец предложения» или «ноль».Слой Masking очень полезен в этих моделях.

F

Вы предоставляете только вход .Две другие вещи (последний вывод и внутренние состояния) уже сохранены в слое с состоянием.

Я сделал ввод = последний вывод только потому, что наша конкретная модель предсказывает следующий шаг .Это то, что мы хотим сделать.Для каждого ввода следующий шаг.

Мы учили этому со смещенной последовательностью в обучении.

G

Это не имеет значения.Нам нужен только последний шаг.

  • Количество последовательностей сохраняется первым :.
  • И только последний шаг рассматривается -1:.

Но если вы хотите знать, вы можете напечатать predicted.shape.В этой модели он равен totalSequences.shape.

Edit 2

I

Во-первых, мы не можем использовать модели «один ко многим», чтобы предсказать будущее, потому что у нас нет данных для этого.Нет возможности понять «последовательность», если у вас нет данных для шагов последовательности.

Итак, этот тип модели следует использовать для других типов приложений.Как я уже говорил, у меня нет хорошего ответа на этот вопрос.Лучше сначала иметь «цель», затем мы решаем, какая модель лучше подходит для этой цели.

II

С помощью «шаг за шагом» я имею в виду ручной цикл.

Если у вас нет результатов последующих шагов, я думаю, что тренироваться невозможно.Это, вероятно, не полезная модель вообще.(Но я не тот, кто знает все)

Если у вас есть выходы, да, вы можете тренировать все последовательности с помощью fit, не беспокоясь о ручных циклах.

III

И вы правы насчет III.Вы не будете использовать повторяющийся вектор во многих ко многим, потому что у вас разные входные данные.

«Один ко многим» и «многие ко многим» - это две разные техники, каждая из которых имеет свои преимущества и недостатки.Один будет полезен для определенных приложений, другой - для других приложений.

...