Вопрос 3
Понимание вопроса 3 является своего рода ключом к пониманию других, поэтому давайте попробуем сначала.
Все повторяющиеся слои в Keras выполняют скрытые петли.Эти циклы совершенно невидимы для нас, но мы можем видеть результаты каждой итерации в конце .
Количество невидимых итераций равно измерению time_steps
.Таким образом, текущие вычисления LSTM происходят относительно шагов.
Если мы передадим ввод с X шагами, будет X невидимых итераций.
Каждая итерация в LSTM будет принимать 3 входа:
- Соответствующий срез входных данных для этого шага
- Внутреннее состояние слоя
- Вывод последней итерации
Итак, возьмем следующий пример изображения, где наш ввод состоит из 5 шагов:
Что будетКерас делать в одном прогнозе?
- Шаг 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.Вы не будете использовать повторяющийся вектор во многих ко многим, потому что у вас разные входные данные.
«Один ко многим» и «многие ко многим» - это две разные техники, каждая из которых имеет свои преимущества и недостатки.Один будет полезен для определенных приложений, другой - для других приложений.