Правильный способ подачи данных временных рядов в LSTM с отслеживанием состояния? - PullRequest
7 голосов
/ 07 октября 2019

Предположим, у меня есть последовательность целых чисел:

0,1,2, ..

и я хочу предсказать следующее целое число, учитывая последние 3 целых числа, например:

[0,1,2]->5, [3,4,5]->6 и т. Д.

Предположим, я настроил свою модель следующим образом:

batch_size=1
time_steps=3
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, time_steps, 1), stateful=True))
model.add(Dense(1))

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

enter image description here

Первый вопрос: верно ли мое понимание?

Примечание. Я нарисовал предыдущие состояния C_{t-1}, h_{t-1}, входякартинка как это выставляется при указании stateful=True. В этой простой проблеме «следующего целочисленного предсказания» производительность должна улучшиться за счет предоставления этой дополнительной информации (при условии, что предыдущее состояние является результатом предыдущих 3 целых чисел).

Это подводит меня к моему основному вопросу: Кажется, что стандартная практика (например, см. Это сообщение в блоге и TimeseriesGenerator утилита предварительной обработки keras), состоит в том, чтобы подавать ступенчатый набор входных данных в модель во время обучения.

Например:

batch0: [[0, 1, 2]]
batch1: [[1, 2, 3]]
batch2: [[2, 3, 4]]
etc

Меня это смущает, потому что кажется, что для этого требуется выход 1-й ячейки Lstm (соответствует 1-му шагу по времени). См. Этот рисунок:

image

Из тензорного потока Документы :

с состоянием : логическое (по умолчаниюЛожь). Если True, последнее состояние для каждого образца с индексом i в пакете будет использоваться в качестве исходного состояния для образца индекса i в следующем пакете.

кажется, что это «внутреннее» состояние isn 't доступно, и все, что доступно, - это конечное состояние. Посмотрите на этот рисунок:

image

Итак, если мое понимание верно (что это явно не так), не должны ли мы подавать неперекрывающиеся окна образцов на модель при использованииstateful=True? Например:

batch0: [[0, 1, 2]]
batch1: [[3, 4, 5]]
batch2: [[6, 7, 8]]
etc

1 Ответ

5 голосов
/ 08 октября 2019

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


Механизм партии и образца (раздел «см. AI» = см. «Дополнительная информация»)

Все модели рассматривают образцы как независимые Примеры;партия из 32 образцов похожа на подачу 1 образца за раз 32 раза (с различиями - см. AI). С точки зрения модели, данные разделяются на размерность пакета batch_shape[0] и размеры элементов batch_shape[1:] - два «не говорят». Единственное отношение между ними - через градиент (см. AI).


Перекрытие по сравнению с серией без перекрытия

Возможно, лучший способ понять это информация -На. Я начну с двоичной классификации временных рядов, а затем увяжу ее с предсказанием: предположим, у вас есть 10-минутные записи ЭЭГ по 240000 временных шагов каждая. Задача: захват или не захват?

  • Поскольку 240 КБ это слишком много для обработки RNN, мы используем CNN для уменьшения размерности
  • У нас есть возможность использовать «скользящие окна»- т.е. кормить подсегмент за раз;давайте использовать 54k

Взять 10 образцов, форма (240000, 1). Как кормить?

  1. (10, 54000, 1), все образцы включены, нарезка как sample[0:54000]; sample[54000:108000] ...
  2. (10, 54000, 1), все образцы включены, нарезка как sample[0:54000]; sample[1:54001] ...

Что из двух вышеперечисленных вы берете? Если (2), ваша нейронная сеть никогда не будет путать захват с отсутствием захвата для этих 10 образцов. Но это также будет невежественным в отношении любого другого образца. То есть он будет массово перекрывать , потому что информация , которую он видит за одну итерацию, почти не отличается (1/54000 = 0,0019%) - так что вы в основном кормите его той же партией несколько раз подряд. Теперь предположим (3):

(10, 54000, 1), все образцы включены, нарезка как sample[0:54000]; sample[24000:81000] ...

Намного более разумно;теперь наши окна перекрываются на 50%, а не на 99,998%.


Прогноз: плохое перекрытие?

Если вы делаете одношаговый прогноз,информационный ландшафт теперь изменился:

  • Скорее всего, длина вашей последовательности равна faaar от 240000, поэтому перекрытия любого вида не страдают от эффекта "одна и та же партия несколько раз"
  • Прогнозирование принципиально отличается от классификации тем, что метки (следующий шаг) различаются для каждой подвыборки, которую вы вводите;классификация использует один для всей последовательности

Это резко меняет вашу функцию потерь, и что является «хорошей практикой» для ее минимизации:

  • Предиктор должен быть устойчивым к своим начальная выборка , особенно для LSTM - поэтому мы тренируемся для каждого такого «запуска», скользя по последовательности, как вы показали
  • Поскольку метки отличаются от шага к временному шагу, функция потерь существенно меняетсявременной шаг, так что риски переоснащения намного меньше

Что мне делать?

Во-первых, убедитесь, что вы понимаете все этопост, так как ничего здесь действительно "необязательно". Затем, вот ключ к перекрытию и отсутствию перекрытия, за пакет :

  1. Сдвиг на одну выборку : модель учится лучше прогнозировать один шаг вперед для каждогоначальный шаг - значение: (1) устойчивость LSTM к начальному состоянию ячейки;(2) LSTM хорошо предсказывает любой шаг вперед, учитывая X шагов позади
  2. Множество выборок, смещенных в позже партия : модель с меньшей вероятностью "запомнит" набор поездов иоверфит

Ваша цель : сбалансировать два;Основное преимущество 1 над 2:

  • 2 может помешать модели, заставив ее забыть просмотренные образцы
  • 1 позволяет модели извлекать лучшего качества особенности, исследуя выборку по нескольким начальным и конечным точкам (меткам) и соответствующим образом усредняя градиент

Должен ли я когда-либо использовать (2) в прогнозе?

  • Если ваша длина последовательности очень велика, и вы можете позволить себе «скользить окно» с ~ 50% его длины, может быть, но зависит от характера данных: сигналов (ЭЭГ)? Да. Акции, погода? Сомневаюсь.
  • Предсказание многих ко многим;более часто можно увидеть (2), в больших и длинных последовательностях.

LSTM с состоянием : на самом деле может быть совершенно бесполезным для вашей проблемы.

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

  • t0=seq[0:50]; t1=seq[50:100] имеет смысл;t0 логически ведет к t1
  • seq[0:50] --> seq[1:51] не имеет смысла;t1 не имеет причинно-следственной связи с t0

Другими словами: не перекрываются в состоянии с сохранением в отдельных пакетах . Та же партия в порядке, как и в случае независимости - нет «состояния» между образцами.

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

  • Желаемый: 100 временных шагов. Можно сделать: 50. Таким образом, мы настроили t0, t1, как в первом пуле выше.
  • Проблема : не просто реализовать программно. Вам нужно будет найти способ подачи в LSTM без применения градиентов - например, замораживание весов или установка lr = 0.

Когда и как LSTM «передает состояния»в состоянии?

  • Когда : только от партии к партии ;образцы полностью независимы
  • Как : в Керасе только от партии к выборке : stateful=True требует указать вас batch_shape вместо input_shape - потому что Keras создает batch_size отдельные состояния LSTM при компиляции

Как указано выше, вы не можете сделать это:

# sampleNM = sample N at timestep(s) M
batch1 = [sample10, sample20, sample30, sample40]
batch2 = [sample21, sample41, sample11, sample31]

Это означает, что 21 причинно следует 10 - и приведет к срыву тренировки. Вместо этого сделайте:

batch1 = [sample10, sample20, sample30, sample40]
batch2 = [sample11, sample21, sample31, sample41]

Пакет или образец: дополнительная информация

«Пакет» - это набор выборок - 1 или больше (предположим, всегдаПоследний за этот ответ). Три подхода к итерации по данным: пакетный градиентный спуск (весь набор данных за один раз), стохастический GD (один образец за раз) и мини-пакетный GD ( в промежутке ). (На практике, однако, мы также называем последний SGD и различаем только BGD - предположим, что так и есть для этого ответа.) Различия:

  • SGD фактически никогда не оптимизирует функцию потерь набора поездов - только ее 'приближения;каждая партия является подмножеством всего набора данных, и вычисленные градиенты относятся только к минимизации потерь этой партии . Чем больше размер партии, тем лучше ее функция потерь похожа на функцию набора поездов.
  • Выше может распространяться на примерную партию по сравнению с выборкой: выборка является приближением партии - или, более худшим приближениемнабор данных
  • Вначале подгонка 16 выборок, а затем еще 16 - это , а не , то же самое, что и подгонка 32 одновременно - поскольку веса обновляются между ними, поэтому выходные данные моделивторая половина изменится
  • Основная причина выбора SGD вместо BGD, на самом деле, не в вычислительных ограничениях, а в том, что лучше в большинстве случаев. Объясняется просто: намного проще использовать BGD, и SGD сходится к лучшим решениям на тестовых данных, исследуя более разнообразное пространство потерь.

БОНУСНЫЕ ДИАГРАММЫ :

image


image

...